none
Nullable<T>: Error

    Question

  • Hi,

    Sorry for the title (that doesn't explain very much).

    I have a struct like this (but with more properties and methods that don't matter for the question):

     

    public struct Variavel<T>//where T:struct// where T:Nullable<T>//:IConvertible, IDisposable
        {
            private T? valor; // valor desconhecido
            private char nome;
    
            public Variavel(T? valor=null, char nome = 'x')
            {
                this.valor = null;
                this.valor = valor;
    
                if (nome.ELetra())
                {
                    this.nome = nome;
                }
                else
                {
                    throw new ArgumentException("");
                }
            }
    
            public T? Valor
            {
                get
                {
                    return valor;
                }
            }
            public char Nome
            {
                get
                {
                    return nome;
                }
    
                set
                {
                    nome = value;
                }
            }
        }
    

     

    I have the errors:

     

    Error 3 The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable<T>' C:\Users\jmcomputador\Documents\Visual Studio 2010\Projects\Calcular\Calcular.Equacoes.DLL\Variavel.cs 16 20 Calcular.Equacoes

     

    Error 4 The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable<T>' C:\Users\jmcomputador\Documents\Visual Studio 2010\Projects\Calcular\Calcular.Equacoes.DLL\Variavel.cs 19 16 Calcular.Equacoes

     

    Error 5 The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable<T>' C:\Users\jmcomputador\Documents\Visual Studio 2010\Projects\Calcular\Calcular.Equacoes.DLL\Variavel.cs 34 19 Calcular.Equacoes

     

    ELetra() checks if the character is a letter or not. Tranlated it means IsLetter().
    I searched, and I understand that, for example, string? doesn't exist because string, as the reference type it is, is already nullable.

     

    But I want to allow reference and value types, making null only the value types. Is there anyway to do this?

    Thanks,

     


    João Miguel

    • Edited by JMCF125 Sunday, January 08, 2012 6:26 PM
    Sunday, January 08, 2012 6:24 PM

Answers

  • I tried that too, but I got confused, and now, where I posted the idea, I got the solution: As I need to turn everything into null regardless of the type, instead of what you said I found a type that may or not be null and then I applied Nullable<T> to that.

    Take a look at this. It's where I found this type. It's called option type. Instead of Nullable<T>, I'm using Nullable<Option<T>>. It solves my problem. The answer is there, but since I can't mark it there, I'll mark this reply as the answer. The answer, by the way, was provided by Mauricio Scheffer.

    Thanks for the help anyway,


    João Miguel


    • Edited by JMCF125 Tuesday, March 06, 2012 8:25 PM
    • Marked as answer by JMCF125 Tuesday, March 06, 2012 9:33 PM
    Tuesday, March 06, 2012 8:24 PM

All replies

  • Monday, January 09, 2012 12:22 AM
  • I would either use a 'class' constraint, allowing the use of Variavel<int?> but not Variavel<int>, or use an IsNull property to store and retrieve null values.
    Monday, January 09, 2012 12:46 PM
  • Your type needs to inherit from the INullable Interface, so that you can use it as a nullable type

    public struct Variavel<T> where T : INullable
    {
       //Your code here
    }
    

    Be sure to check out my [url=https://github.com/RexGrammer]GitHub[/url]... Review my programs, all advice appreciated :) If I helped don't be afraid to click the [img]http://cdn2.dreamincode.net/dreamincode/forums/public/style_images/DIC/add.png.pagespeed.ce.GYjDzBOEo6.png[/img] button... :)
    Monday, January 09, 2012 12:50 PM
  • I got the sample from my brain.

    ? makes a value type nullable.

    Example: int? makes a nullable int.


    João Miguel
    • Edited by JMCF125 Monday, January 09, 2012 5:56 PM
    Monday, January 09, 2012 5:37 PM
  • Maybe I'm doing something wrong, but now the beggining of the class is like this:

    public struct Variavel<T> where T : class
    

    And this:

    Variavel<double?> vd;
    
    still doesn't work.


    João Miguel
    Monday, January 09, 2012 5:51 PM
  • That works, but there's another problem now.

    I get this error

    Error 3 A value of type '<null>' cannot be used as a default parameter because there are no standard conversions to type 'T' C:\Users\jmcomputador\documents\visual studio 2010\Projects\Calcular\Calcular.Equacoes.DLL\Variavel.cs 19 27 Calcular.Equacoes

     

    In here:

    public Variavel(T valor=null, char nome = 'x')
            {
                this.valor = null;
                this.valor = valor;
    
                if (nome.ELetra())
                {
                    this.nome = nome;
                }
                else
                {
                    throw new ArgumentException("");
                }
            }
    


    Thank you,

     

    P.S.

    Don't worry, your post will be marked as an anwser after this problem is solved.


    João Miguel
    Monday, January 09, 2012 5:54 PM
  • And this: 
    Variavel<double?> vd;
    
    still doesn't work.

     


    Right. I forgot. You need to not put any constraint. Something like this maybe:
    public struct Variavel<T>
    {
            private T valor;
            private bool isNull;
            private char nome;
    
            public Variavel(T valor, char nome = 'x')
            {
                    this.valor = valor;
                    isNull = false;
    
                    if (nome.ELetra())
                    {
                            this.nome = nome;
                    }
                    else
                    {
                            throw new ArgumentException("");
                    }
            }
    
    
            public Variavel(char nome = 'x')
            {
                    this.valor = default(T);
                    isNull = true;
    
                    if (nome.ELetra())
                    {
                            this.nome = nome;
                    }
                    else
                    {
                            throw new ArgumentException("");
                    }
            }
    
            public T Valor
            {
                    get
                    {
                            if(isNull) throw new InvalidOperationException("Value is null");
                            return valor;
                    }
            }
            public bool IsNull
            {
                    get
                    {
                            return isNull;
                    }
            }
            public char Nome
            {
                    get
                    {
                            return nome;
                    }
    
                    set
                    {
                            nome = value;
                    }
            }
    }
    

    Tuesday, January 10, 2012 3:54 PM
  • But I want to make T valor null by default.

    public Variavel(T valor = null, char nome = 'x')
            {
                    this.valor = valor;
                    isNull = false;
    
                    if (nome.ELetra())
                    {
                            this.nome = nome;
                    }
                    else
                    {
                            throw new ArgumentException("");
                    }
            }
    


    And return null in the property:

    public T Valor
            {
                    get
                    {                        
                            return valor;
                    }
            }
    

    You may be asking why, and the reason is that I want a new Variavel<T> with an unknown value by default.

    So in this struct, null doesn't mean just null, it also means unknown, that, depending on the given data, might get a known value of the nullable type T.

    And this is what I can't do.


    João Miguel
    Tuesday, January 10, 2012 4:10 PM
  • I'm not sure I understand. You want to have the possibility of a value known as being null, as well as an unknown value? Then you shouldn't be using default parameters. Use distinct constructors, and an IsUnknown property.
    Wednesday, January 11, 2012 12:40 PM
  • Maybe I didn't explain it very well.

    I want to have this structure, that, by default, when instanciated, will be a new Variavel<T> whose type is an unknown value (that I set as null).

    Even after created and fully assigned, this instance has an unknown value (given in the instance as null), so T valor must be null. If the value becames known, T valor is no longer null.

    I may know there's a value in the new instance of the struct, but that doesn't implie that I know the value at the moment with the given data. Unlike what you said "You want to have the possibility of a value known as being null", a known value is never null, and an unknown value is null at that time, before it becames known.

    Thanks and sorry for the delay,


    João Miguel
    Thursday, January 12, 2012 8:54 PM
  • Oh, I forgot it, T must be a nullble value, such as string or double?, or any other reference type or nullable struct.

    Please help,


    João Miguel
    Friday, January 13, 2012 5:13 PM
  • Just remeber: Because this is math, I need to have null value different from 0 value, so default(type) doesn't work (in double it would be 0, in string null).
    João Miguel
    Friday, January 13, 2012 8:43 PM
  • I'm not sure if this is the option in your struct, but this works fine for me:

    public struct Variavel<T>
        {
            private Nullable<T> valor;
            private bool isNull;
            private char nome;
    
            public Variavel(Nullable<T> valor=null, char nome = 'x')
            {
                
                this.valor = valor;
                isNull = false;
    
                this.nome = nome;
            }
    
    
            public Variavel(char nome = 'x')
            {
                this.valor = default(T);
                isNull = true;
    
                this.nome = nome;
            }
    
            public Nullable<T> Valor
            {
                get
                {
                    if (isNull) throw new InvalidOperationException("Value is null");
                    return valor;
                }
            }
            public bool IsNull
            {
                get
                {
                    return isNull;
                }
            }


    Jack Ernest Care About Your Craft
    Saturday, January 14, 2012 5:16 AM
  • Hi Jack,

    Thanks for the reply, but remeber that in Nullable<T>, T must be a non-nullable value, a struct, and I want Varaiavel<T> to support also classes. I want to keep nullable types null, and turn non-nullble types into null.

    What you did only works with non-nullable types.


    João Miguel
    Saturday, January 14, 2012 1:14 PM
  • I agree but you have to know that generics type does not support constraints to Nullable structs

    http://msdn.microsoft.com/en-us/library/d5x73970(v=vs.80).aspx

    where T: struct

    The type argument must be a value type. Any value type except Nullable can be specified. See Using Nullable Types (C# Programming Guide) for more information.

    My example is the same as your first example just Nullable instead of '?' which did not build. 

    I don't think there is any other way then, It looks like you already tried all options , if you put class you will not be able to pass Nullable, because it is struct and if you make constraint struct you can restrict it to be Nullable and otherwise your default Varlor in constructor will not compile, because not all T accept null. I'm still not sure why you try to make it null by default - if null for any reference object or Nullable struct is default value anyway.

     

    Good luck

    Jack


    Jack Ernest Care About Your Craft
    • Marked as answer by JMCF125 Saturday, January 14, 2012 4:19 PM
    • Unmarked as answer by JMCF125 Saturday, January 14, 2012 4:38 PM
    Saturday, January 14, 2012 3:54 PM
  • There must be another option.

    I just want to keep nullable types null and turn non-nullable ones into nullable types!

    Isn't this possible? Why?


    João Miguel
    • Edited by JMCF125 Saturday, January 14, 2012 5:01 PM
    Saturday, January 14, 2012 4:38 PM
  • Now I have another error:

     

    Error 4 The type 'System.Data.SqlTypes.INullable' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. C:\Users\jmcomputador\Documents\Visual Studio 2010\Projects\Calcular\TesteCalcular\Program.cs 298 17 TesteCalcular

    In this line:

    Variavel<Fracc> v = new Variavel<Fracc>(null);

    Fracc is a struct.

    Why the error? What should I do?

     


    João Miguel
    • Edited by JMCF125 Saturday, January 14, 2012 5:18 PM
    Saturday, January 14, 2012 5:17 PM
  • Can't anyone help me?

    I've been thinking about this since 1 week ago and I still haven't fond the answer!


    João Miguel
    Sunday, January 15, 2012 12:54 PM
  • Hello,

    Did you try to add System.Data as a Reference to your project? It seems like it is missing. You can do it by right click on Project Add Reference.

    Regards

    Jack


    Jack Ernest Care About Your Craft
    Tuesday, January 17, 2012 12:21 AM
  • a known value is never null, and an unknown value is null at that time, before it becames known.

    Instead of insisting to return null, do as the Nullable structure does: have a HasValue property return false.
    Wednesday, January 18, 2012 11:15 AM
  • Sorry for the delay but,

    That helps and eliminates the error, however the big problem still stands:

    I can't turn non-nullable into nullable types and remain with the nullable types!

    Thanks anyway,


    João Miguel

    • Edited by JMCF125 Friday, January 20, 2012 6:14 PM
    Friday, January 20, 2012 6:13 PM
  • My problem didn't remains unanswered, and that's why I unmarked the marked answers.
    João Miguel
    Friday, January 20, 2012 6:16 PM
  • But that is limitation of the .NET framework and that is the answer. I don't think you can do more than report it to Microsoft suggestion/bugs under Visual Studio and .NET Framework there is always hope that they can provide some solution in .NET 5.0+ in current .NET Framework you just can't do it.

    http://connect.microsoft.com/directory/accepting-bugs

     

    Regards

     


    Jack Ernest Care About Your Craft
    Friday, January 20, 2012 9:23 PM
  • How can I do that?

    How can I  report that to Microsoft?


    João Miguel
    Friday, January 20, 2012 9:46 PM
  • You can just go to this site (if its first time you will have to register)

    http://connect.microsoft.com/VisualStudio and click submit bug and pick form

    Visual Studio, .NET Framework, and Silverlight Bug Form 

     

    Regards

     

     


    Jack Ernest Care About Your Craft
    • Marked as answer by JMCF125 Saturday, January 21, 2012 12:08 PM
    • Unmarked as answer by JMCF125 Sunday, March 04, 2012 7:43 PM
    Saturday, January 21, 2012 2:22 AM
  • That is the only way.

    I posted the idea here.


    João Miguel
    Saturday, January 21, 2012 12:10 PM
  • Hi, sorry for the delay, but I have found what might be the solution to my problem.

    It's called SASA. In the place I posted my idea, Mauricio Scheffer commented, saying that this mechanism already existed, without any changes to the CLR. Yet, I couldn't find this ToNullable<T> class or struct. I tried to find manuals where I could see where it is, but I couldn't find them.

    I really need help with this, I've been doing other projects, however one of them is entirelly dependent on this.

    Thanks,


    João Miguel

    Sunday, March 04, 2012 7:40 PM
  • I'll have to remove the answer tick, because now the question is open again. If I find the answer I'm looking for, I'll mark that, otherwise, I'll remark this one.

    João Miguel

    Sunday, March 04, 2012 7:43 PM
  • Create your own Nullable structure. Allow its type parameter to be anything. Don't put any constraint on your Variavel structure and use your custom Nullable in place of Nullable<T>
    Monday, March 05, 2012 12:55 PM
  • I tried that too, but I got confused, and now, where I posted the idea, I got the solution: As I need to turn everything into null regardless of the type, instead of what you said I found a type that may or not be null and then I applied Nullable<T> to that.

    Take a look at this. It's where I found this type. It's called option type. Instead of Nullable<T>, I'm using Nullable<Option<T>>. It solves my problem. The answer is there, but since I can't mark it there, I'll mark this reply as the answer. The answer, by the way, was provided by Mauricio Scheffer.

    Thanks for the help anyway,


    João Miguel


    • Edited by JMCF125 Tuesday, March 06, 2012 8:25 PM
    • Marked as answer by JMCF125 Tuesday, March 06, 2012 9:33 PM
    Tuesday, March 06, 2012 8:24 PM