Nullable<T>: Error
-
Sunday, January 08, 2012 6:24 PM
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.EquacoesError 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.EquacoesELetra() 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
All Replies
-
Monday, January 09, 2012 12:22 AM
I have used ?? but not ?
Where do you get the sample from?
chanmm
chanmm -
Monday, January 09, 2012 12:46 PMI 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.
- Marked As Answer by Bob ShenMicrosoft Contingent Staff, Moderator Thursday, January 19, 2012 2:20 AM
- Unmarked As Answer by JMCF125 Friday, January 20, 2012 6:14 PM
-
Monday, January 09, 2012 12:50 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... :)- Marked As Answer by Bob ShenMicrosoft Contingent Staff, Moderator Thursday, January 19, 2012 2:20 AM
- Unmarked As Answer by JMCF125 Friday, January 20, 2012 6:14 PM
-
Monday, January 09, 2012 5:37 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:51 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:
still doesn't work.Variavel<double?> vd;
João Miguel -
Monday, January 09, 2012 5:54 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 -
Tuesday, January 10, 2012 3:54 PM
And this:
still doesn't work.Variavel<double?> vd;
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 4:10 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 -
Wednesday, January 11, 2012 12:40 PMI'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.
-
Thursday, January 12, 2012 8:54 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 -
Friday, January 13, 2012 5:13 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 8:43 PMJust 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 -
Saturday, January 14, 2012 5:16 AM
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 1:14 PM
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 3:54 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 -
Saturday, January 14, 2012 4:38 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 5:17 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
-
Sunday, January 15, 2012 12:54 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 -
Tuesday, January 17, 2012 12:21 AM
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- Marked As Answer by Bob ShenMicrosoft Contingent Staff, Moderator Thursday, January 19, 2012 2:21 AM
- Unmarked As Answer by JMCF125 Friday, January 20, 2012 6:13 PM
-
Wednesday, January 18, 2012 11:15 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.- Marked As Answer by Bob ShenMicrosoft Contingent Staff, Moderator Thursday, January 19, 2012 2:21 AM
- Unmarked As Answer by JMCF125 Friday, January 20, 2012 6:15 PM
-
Friday, January 20, 2012 6:13 PM
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:16 PMMy problem didn't remains unanswered, and that's why I unmarked the marked answers.
João Miguel -
Friday, January 20, 2012 9:23 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:46 PM
How can I do that?
How can I report that to Microsoft?
João Miguel -
Saturday, January 21, 2012 2:22 AM
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 -
Saturday, January 21, 2012 12:10 PM
-
Sunday, March 04, 2012 7:40 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:43 PMI'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
-
Monday, March 05, 2012 12:55 PMCreate 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>
-
Tuesday, March 06, 2012 8:24 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

