This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
How to check if an object is nullable?
Determine if reflected property can be assigned null
How can I properly identify if a variable (or a class member) of given type can take null? More specifically how to handle Nullable<T> since it is not a reference type? Or any other type that may have some weirdo implicit conversion defined on it.
My gut feeling is that the only sure way to find out is to try{} catch{} it and see if it blows up... But maybe there are some tricks to it.
It's not clear what information you do have about the type in question.
try/catch will do things at execution time, which isn't really what you want.
For a concrete type, you should be able to know just by knowing the variable type. It should be pretty obvious - or if it's not, you've got bigger problems than not knowing about nullity :)
For a generic type, I've found this is quite useful:
if (default(T) == null)
For a Type reference (e.g. if you're using reflection) you could use:
if (!type.IsValueType || Nullable.GetUnderlyingType(type) != null)
bool canBeNull = !type.IsValueType || (Nullable.GetUnderlyingType(type) != null);
Only reference types can actually hold a null reference; the special case of Nullable<T> is all syntactic sugar; the resulting value is not actually null (since Nullable<T> is a value type, too, so it cannot hold a null reference), it's just a Nullable<T> with default(T) as its Value and HasValue = false.
So it depends on what you're asking.
If you're trying to determine if the type qualifies for in-code assignment to the null (Nothing in VB.NET) literal, then it's:
All reference types
Nullable<T>
If you're trying to determine if the type qualifies to hold a bona-fide null reference, then it's
All reference types
As for using reflection to inspect a particular type at runtime, checking IsValueType should be enough to get you what you need, even if it's the former (just add a special case in your code for Nullable<T>).
Nullable exposes the HasValue property so if you want to check if a value type is nullable then just check if it exposes that Property.
Related
This question already has answers here:
How does the assignment of the null literal to a System.Nullable<T> type get handled by .Net (C#)?
(5 answers)
Closed 8 years ago.
Recently while revising one of the concept I came across a situation which is interesting and I want to know why this happens.
We know one concept that we can't assign null values to Value types i.e. Struct, int, DateTime, etc.
In order to assign null we need nullable type i.e.
int i should be replaced with Nullable<int> i = null
But if we see Nullable<T> it is also of type struct then how come null can be assigned without stating any error? Why Microsoft contradicted it's own statement of "Null can't be assigned to value type"
If someone knows the reason behind this?
Because Nullable<T> has compiler-level support; null, in the context of Nullable<T>, is essentially a value with a HasValue flag of false, where-as a non-null value has a HasValue flag of true. And similarly, "lifted" operators are derived from the defined operators. Likewise, Nullable<T> has CLI support, in terms of boxing: a boxed Nullable<T> with HasValue of false becomes null, not a new box instance.
Basically: it all just comes down to because that is how they defined it should work.
People wanted nullable value types: Microsoft figured out a way for that to happen.
This question already has answers here:
What is the purpose of a question mark after a value type (for example: int? myVariable)?
(9 answers)
Closed 9 years ago.
I am trying to find the meaning of the symbol/operator ? in C#.
Usage example:
private Point? _point = null;
I think it has to do something with the null value.
of course I looked on MSDN C# Operators page but and didn't find an answer there.
Can someone give me a link or explain this operator?
It is a shorthand for Nullable<T>, i.e. Point? is the same as Nullable<Point>. This allows you to assign a null value for value types.
See the MSDN reference on Using Nullable Types.
NOTE, in this context it is not an operator, it is a shorthand syntax.
Adding to previous answer
In a simple way, usually in C#, we have value type and reference type, reference types have reference and can be assigned null values but value type cannot be assigned null because they don't have any reference, by term reference its simply 32 or 64 bit number which is not address of virtual memory space of the process that the referred-to object lives whereas pointer is actual virtual memory space of the process that the referred-to object lives, C# has concept of both pointer (unsafe) as well as reference.
Coming back to question, T? is syntactic sugar for Nullable<T>
Huge reason why we use it is sql accepts null value for int, float or any types that are value types in C# so the problem usually arises when someone tries to get value from sql which is an int but has null, we get error when we try to enter null on the value types so the solution is nullable type.
References:
http://blogs.msdn.com/b/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx
http://blogs.msdn.com/b/ericlippert/archive/2012/03/26/null-is-not-false.aspx
This question already has answers here:
C# okay with comparing value types to null
(11 answers)
Closed 9 years ago.
This is not to solve any particular problem. Simply a compiler question.
Why does the following code not result in compile error? It's comparing a reference type to primitive type. Both null and false have to to be interpreted into something for the compiler to do comparison. Or is the parser simply scanning for such pattern and replace it with false?
if(null == false) { }
It's legal because the lifted comparison operator is used. If you compare a bool to a null, both the bool and null get implicitly converted to Nullable<bool> and the comparison operator for Nullable<bool> ends up being used. You get a warning because obviously, it is always false.
Tejas's answer is correct. To more specifically address some of your points:
Why does the following code not result in compile error?
The question is not answerable; it does not produce an error because it is legal code, but that's a tautology.
If your question is actually "which section of the C# specification makes this legal?", then that's an answerable question. The section on lifted equality operators makes it legal.
It's comparing a reference type to primitive type.
It is not. First off, avoid the term "primitive type"; the specification does not clearly define it and it is not a useful concept in C#. You meant to say I think that it is comparing a value of reference type to a value of value type.
Second, that's not correct either. The null literal is not of reference type or value type; it is of no type. It is convertible to any nullable value type or any reference type, but it is of no type just by itself.
In this case the null literal is converted to the nullable bool type.
Both null and false have to be interpreted into something for the compiler to do comparison.
Correct. They are interpreted as nullable bools.
is the parser simply scanning for such pattern and replace it with false?
No, but that's an excellent guess. The compiler would constant-fold, say, true == false down to false, but it does not do folding optimizations that involve nullable value types. The language could be redesigned to support constant folding on operations with nullable value type operands; had nullable value types counterfactually been in version one, the proposed feature likely would have been supported.
Section 7.10.6 of the language specification (Reference type equality operators) states:
The x == null construct is permitted even though T could represent a value type, and the result is simply defined to be false when T is a value type.
This provision requires that null == false be false, and not a compiler error.
This question already has answers here:
How can I call default(T) with a type? [duplicate]
(3 answers)
Closed 10 years ago.
I am using reflection to get all the properties of an object. I then need to see if any of those property’s values are the default of whatever type they happen to be. Below is my current code. It is complaining that the namespace or type could not be found. This leads me to believe that it has something to do with how c# does implicit type coercion. Since I am grabbing the type at run time it does not know how to compare it or something not really clear on that.
I was hoping to avoid a switch case comparing on the name of the type that comes in but right now that is looking like my only option unless the brilliant people on StackOverflow can lead me in the right direction.
private bool testPropertyAttribute(PropertyInfo prop)
{
dynamic value = prop.GetValue(DataObject, null);
Type type = prop.PropertyType;
/* Test to see if the value is the defult of its type */
return (value == default(prop.PropertyType)
}
== for object will always mean: reference equality. For a reference, the default is always null, so if !prop.PropertyType.IsValueType, then you only need a null check. For value-types, you will be boxing. So reference equality will always report false, unless they are both Nullable<T> for some T, and both are empty. However, to get a "default" value-type (prop.PropertyType.IsValueType), you can use Activator.CreateInstance(prop.PropertyType). Just keep in mind that == is not going to do what you want here. Equals(x,y) might work better.
You can do this you just cannot rely on the == operator to do the work. You'll want to use .Equals or object.ReferenceEquals to do the comparison.
Could someone please be kind enough to explain why calling ToString() on an empty reference type causes an exception (which in my mind makes perfect sense, you cant invoke a method on nothing!) but calling ToString() on an empty Nullable(Of T) returns String.Empty? This was quite a surprise to me as I assumed the behaviour would be consistent across types.
Nullable<Guid> value = null;
Stock stock = null;
string result = value.ToString(); //Returns empty string
string result1 = stock.ToString(); //Causes a NullReferenceException
Nullable<T> is actually a struct that has some compiler support and implementation support to behave like a null without actually being null.
What you are seeing is the collision between the implementation allowing you to treat it naturally as a null as you would any other reference type, but allowing the method call to happen because the Nullable<T> isn't actually null, the value inside it is null.
Visually it looks like it shouldn't work, this is simply because you cannot see what is done in the background for you.
Other such visual trickery can be seen when you call an extension method on a null reference type... the call works (against visual expectation) because under the hood it is resolved into a static method call passing your null instance as a parameter.
How does a Nullable<T> type work behind the scenes?
Nullable is a value type and the assignment to null causes it to be initialized with Value=null and HasValue=false.
Further, Nullable.ToString() is implement as follows:
public override string ToString()
{
if (!this.HasValue)
{
return "";
}
return this.value.ToString();
}
So what you are seeing is expected.
It is a bit tricky with nullable types. When you set it to null it is actualy not null cause it is not reference type (it is value type). When you initialize such variable with null it creates new sctructure instance where HasValue property is false and it's Value is null, so when you call ToString method it works well on structure instance.
The exception raised by calling default(object).ToString() is called NullReferenceException for a reason, it's calling a method on a null reference. default(int?) on the other hand, is not a null reference, because it's not a reference; it is a value type with a value that is equivalent to null.
The big practical point, is that if this was done, then the following would fail:
default(int?).HasValue // should return false, or throw an exception?
It would also screw-up the way we have some ability to mix nullables and non-nullables:
((int?)null).Equals(1) // should return false, or throw an exception?
And the following becomes completely useless:
default(int?).GetValueOrDefault(-1);
We could get rid of HasValue and force comparison with null, but then what if the equality override of the value-type that is made nullable can return true when compared to null in some cases. That may not be a great idea, but it can be done and the language has to cope.
Let's think back to why nullable types are introduced. The possibility that a reference type can be null, is inherent in the concept of reference types unless effort is taken to enforce non-nullability: Reference types are types that refer to something, and that implies the possibility of one not referring to anything, which we call null.
While a nuisance in many cases, we can make use of this in a variety of cases, such as representing "unknown value", "no valid value" and so on (we can use it for what null means in databases, for example).
At this point, we've given null a meaning in a given context, beyond the simple fact that a given reference doesn't refer to any object.
Since this is useful, we could therefore want to set an int or DateTime to null, but we can't because they aren't types that refer to something else, and hence can't be in a state of not referring to anything any more than I as a mammal can lose my feathers.
The nullable types introduced with 2.0 give us a form of value types that can have the semantic null, through a different mechanism than that of reference types. Most of this you could code yourself if it didn't exist, but special boxing and promotion rules allow for more sensible boxing and operator use.
Okay. Now let's consider why NullReferenceExceptions happen in the first place. Two are inevitable, and one was a design decision in C# (and doesn't apply to all of .NET).
You try to call a virtual method or property, or access a field on a null reference. This has to fail, because there's no way to look up what override should be called, and no such field.
You call a non-virtual method or property on a null reference which in turn calls a virtual method or property, or accesses a field. This is obviously a variant on point one, but the design decision we're coming to next has the advantage of guaranteeing this fails at the start, rather than part-way through (which could be confusing and have long-term side-effects).
You call a non-virtual method or property on a null reference which does not call a virtual method or property, or access a field. There's no inherent reason why this should not be allowed, and some languages allow it, but in C# they decided to use callvirt rather than call to force a NullReferenceException for the sake of consistency (can't say I agree, but there you go).
None of these cases apply in any way to a nullable value type. It is impossible to put a nullable value type into a condition in which there is no way to know which field or method override to access. The whole concept of NullReferenceException just doesn't make sense here.
In all, not throwing a NullReferenceException is consistent with the other types - types through it if and only if a null reference is used.
Note that there is a case where calling on a null nullable-type throws, it does so with GetType(), because GetType() is not virtual, and when called on a value-type there is always an implied boxing. This is true of other value types so:
(1).GetType()
is treated as:
((object)1).GetType()
But in the case of nullable types, boxing turns those with a false HasValue into null, and hence:
default(int?).GetType()
being treated as:
((object)default(int?)).GetType()
which results in GetType() being called on a null object, and hence throwing.
This incidentally brings us to why not faking NullReferenceType was the more sensible design decision - people who need that behaviour can always box. If you want it to through then use ((object)myNullableValue).GetString() so there's no need for the language to treat it as a special case to force the exception.
EDIT
Oh, I forgot to mention the mechanics behind NullReferenceException.
The test for NullReferenceException is very cheap, because it mostly just ignores the problem, and then catches the exception from the OS if it happens. In other words, there is no test.
See What is the CLR implementation behind raising/generating a null reference exception? and note how none of that would work with nullable value types.
If you investigate Nullable<> definition, there is an override ToString definition. In this function, ToString is overriden to return String.Empty.
// Summary:
// Returns the text representation of the value of the current System.Nullable<T>
// object.
//
// Returns:
// The text representation of the value of the current System.Nullable<T> object
// if the System.Nullable<T>.HasValue property is true, or an empty string ("")
// if the System.Nullable<T>.HasValue property is false.
public override string ToString();
On the otherhand, Stock is a custom class, which I assume ToString is not overriden. Thus it returns NullReferenceException since it uses default behaviour.
As per MSDN Remarks
Guid.ToSTring() method Returns a string representation of the
value of this Guid instance, according to the provided format
specifier.
As per MSDN Remarks on Nullable
A type is said to be nullable if it can be assigned a value or can be
assigned null, which means the type has no value whatsoever.
Consequently, a nullable type can express a value, or that no value
exists. For example, a reference type such as String is nullable,
whereas a value type such as Int32 is not. A value type cannot be
nullable because it has enough capacity to express only the values
appropriate for that type; it does not have the additional capacity
required to express a value of null.