I want to check if a reference type is null. I see two options (_settings is of reference type FooType):
if (_settings == default(FooType)) { ... }
and
if (_settings == null) { ... }
How do these two perform differently?
There's no difference. The default value of any reference type is null.
MSDN's C# reference page for default keyword: https://msdn.microsoft.com/en-us/library/25tdedf5.aspx.
Now that we don't need to pass the type to default anymore, default is preferred.
It is just as readable
It can be used both for value and reference types
It can be used in generics
if (_settings == default) { ... }
Also, after calling
obj = enumerable.FirstOrDefault();
it makes more sense to test for default after that and not for null. Otherwise it should have been FirstOrNull, but value dont have a null value but do have a default.
There is no difference, but second one is more readable. The best place to use default is when you deal with generics. Common code is return default(T);
Not different but I think
if (_settings == null) { ... }
is clearer.
My understanding is they are not different. It only matters when you are dealing with value types.
I would definitely go with the specific check against null. Because if the type of the _settings class ever changes you may run into reference issues. At minimum it would require a change to the code breaking the open/close policy.
if( _settings == null ) {...}
This IMO is safer and cleaner.
As has been mentioned, there is no difference... but you might want to use default(<type>) anyway, to handle the cases where it's not a reference type. Typically this is only in generics, but it's a good habit to form for the general case.
Related
Often when using nullable types I get following pattern inside my code (test for value, call a function):
Type? a;
if(a.HasValue)
{
SomeFunction(a.Value);
}
Is there some clever shorthand for this? Does this pattern have a name? Perhaps this question is misguided and I should be using nullables differently...
The null conditional can do this, but to make it work you'll want to make SomeFunction an extension method of Type
public static void SomeFunction(this Type? a)
{
// do stuff
}
then you can do
Type? a;
a?.SomeFunction()
In WPF/UWP, we often have to deal with adding change notification to every single property. This code is repeating and verbose. People did learn tricks to absract this. Often storing the actuall value in some kind of String Key collection. Wich then takes care of any change notification.
A simple way would (as others have said) be to use Expansion methods with the null-conditional operatiors. Wich of coruse might become quite tedious quickly.
Maybe you could make something similar to the TryParse pattern? It gives you your normal parsing results via a out parameter, and the return value tells if the parsing failed or not. Except in this case, you hand in the function to be called as a delegate and would get the return if it failed due to null values?
The Static and thus non-overrideable Equals Method, calls the instance (and thus overrideable) one after doing null checks. But in this case, null is a valid input for both values.
But in all cases you still need a way to tell that the operation failed due to a null. So you will not really get around checking something.
If SomeFunction takes Type you're need to pass a.Value, no shortcuts here.
BTW. If you have an aversion to a.HasValue then if(p != null) is another option.
void SomeFuntion(int i) {Console.WriteLine(i);}
int? p = null;
if(p != null) SomeFuntion(p.Value);
Say I have some code such as the following:
var someCollection = new int[] {};
var result = someCollection.SingleOrDefault();
I then want to determine if result was the default value. However, I want to do so in a maintainable way so that if the element type of someCollection changes, the rest of the code doesn't require changing.
The way this typically seems to be done (in a general sense) is result == null. In this case, of course, the type is not a reference type, so this won't work.
An improvement that avoids this assumption is result == default(int). However, changing the element type would also require changing the argument to default, so the requirement of only changing the type in one place is still not met.
Acceptance Criteria
Built-in logic is preferred over custom logic.
Elegant and concise code is preferred.
Efficient code is preferred. (For reference types, only a reference comparison should occur.)
You can use the default keyword. Since you don't know what the type will be, you can use generics.
public bool IsDefault<T>(T value)
{
return EqualityComparer<T>.Default.Equals(value, default(T));
}
Stealing from Sam, and improving it:
public static bool IsDefault<T>(this T value)
{
return value == null || value.Equals(default(T));
}
No need for a type check. The JIT will make it work because it knows what T is at JIT time.
Note that if the type overrides Equals then it might say false even
when it is default(T) and it might say true even when it is not.
– commented by Eric Lippert
I think this will work.
public static bool IsDefault<T>(this T value)
{
var isValueType = typeof(T).IsValueType;
if (isValueType)
return value.Equals(default(T));
else
return value == null;
}
However, for value types, I figure this will call their overloaded Equals methods, which may or may not be a problem.
Today I stumbled upon an interesting bug I wrote. I have a set of properties which can be set through a general setter. These properties can be value types or reference types.
public void SetValue( TEnum property, object value )
{
if ( _properties[ property ] != value )
{
// Only come here when the new value is different.
}
}
When writing a unit test for this method I found out the condition is always true for value types. It didn't take me long to figure out this is due to boxing/unboxing. It didn't take me long either to adjust the code to the following:
public void SetValue( TEnum property, object value )
{
if ( !_properties[ property ].Equals( value ) )
{
// Only come here when the new value is different.
}
}
The thing is I'm not entirely satisfied with this solution. I'd like to keep a simple reference comparison, unless the value is boxed.
The current solution I am thinking of is only calling Equals() for boxed values. Doing a check for a boxed values seems a bit overkill. Isn't there an easier way?
If you need different behaviour when you're dealing with a value-type then you're obviously going to need to perform some kind of test. You don't need an explicit check for boxed value-types, since all value-types will be boxed** due to the parameter being typed as object.
This code should meet your stated criteria: If value is a (boxed) value-type then call the polymorphic Equals method, otherwise use == to test for reference equality.
public void SetValue(TEnum property, object value)
{
bool equal = ((value != null) && value.GetType().IsValueType)
? value.Equals(_properties[property])
: (value == _properties[property]);
if (!equal)
{
// Only come here when the new value is different.
}
}
( ** And, yes, I know that Nullable<T> is a value-type with its own special rules relating to boxing and unboxing, but that's pretty much irrelevant here.)
Equals() is generally the preferred approach.
The default implementation of .Equals() does a simple reference comparison for reference types, so in most cases that's what you'll be getting. Equals() might have been overridden to provide some other behavior, but if someone has overridden .Equals() in a class it's because they want to change the equality semantics for that type, and it's better to let that happen if you don't have a compelling reason not to. Bypassing it by using == can lead to confusion when your class sees two things as different when every other class agrees that they're the same.
Since the input parameter's type is object, you will always get a boxed value inside the method's context.
I think your only chance is to change the method's signature and to write different overloads.
How about this:
if(object.ReferenceEquals(first, second)) { return; }
if(first.Equals(second)) { return; }
// they must differ, right?
Update
I realized this doesn't work as expected for a certain case:
For value types, ReferenceEquals returns false so we fall back to Equals, which behaves as expected.
For reference types where ReferenceEquals returns true, we consider them "same" as expected.
For reference types where ReferenceEquals returns false and Equals returns false, we consider them "different" as expected.
For reference types where ReferenceEquals returns false and Equals returns true, we consider them "same" even though we want "different"
So the lesson is "don't get clever"
I suppose
I'd like to keep a simple reference comparison, unless the value is boxed.
is somewhat equivalent to
If the value is boxed, I'll do a non-"simple reference comparison".
This means the first thing you'll need to do is to check whether the value is boxed or not.
If there exists a method to check whether an object is a boxed value type or not, it should be at least as complex as that "overkill" method you provided the link to unless that is not the simplest way. Nonetheless, there should be a "simplest way" to determine if an object is a boxed value type or not. It's unlikely that this "simplest way" is simpler than simply using the object Equals() method, but I've bookmarked this question to find out just in case.
(not sure if I was logical)
What's the preferred way of checking if the value is null?
Let's say we have some entity, which has properties, which can be null (some of them or all of them).
And I wish to check this in runtime, if some property is actually null or not.
Would you use simple Entity.Property != null check in this case or would you implement a specific method, let's say like
bool HasProperty() {
return Property != null;
}
What would you choose and why?
For property values which can be null, my preference is to do the following
Have the property containing the value which can possibly be null
Have another property prefixed with Has and the rest containing the original property name which determines if the other property is non-null
Add an assert into the original property if it's accessed when null
In this example it would be
SomeType Property {
get {
Contract.Requires(HasProperty);
return _property; }
}
bool HasProperty {
get { return _property != null; }
}
The reasoning behind this is that C# does not have a standard way of describing whether or not a value can be null. There are many different conventions and techniques avalaible but simply no standard. And not understanding the null semantics around a value leads to missed null checks and eventually NullReferenceExceptions.
I've found the best way to express this is to make the null feature of a property explicit in the type itself by adding the Has property if and only if the property can be null. It's not a perfect solution but I've found it works well in large projects.
Other solutions I've tried
Do Nothing: This just fails over and over again
Using an explicit Maybe<T> or Option<T> type in the flavor of F#. This works but I find I receive a lot of push-back from developers who've never done functional programming and it leads to a rejection of the idea entirely in favor of #1.
Just check if the property itself is null, there is no need to create a method for this. Properties are really just methods that are generated by the compiler.
There is no pattern that covers this. In fact, anything you do to try and make this "easier" could be considered an anti-pattern.
"Hey, don't check if the property is null, use the Is[Property Name]Null property"
Uh, no.
I check only against null, because every nullable type does internally exactly what you described (but the internal method is called HasValue instead of HasProperty):
http://msdn.microsoft.com/de-de/library/b3h38hb0.aspx
If Property is something that isn't public, then you would need a method like HasProperty(). Also, if you implement your "nullness" in another way, it would also be good to have a HasProperty() method.
Null is not necessarily bad. I think it all depends on why you need to check for null to determine how you should check for it.
I would choose to write a separate Has* property only if the property is auto-initializing (i.e. just getting it might cause, say, an empty collection to be allocated) and it makes a performance difference. If getting the property is cheap (as it should be; in some cases you just can't help having it make a difference, though), there's no need for a superfluous Has method.
So no Has for the general case:
public string Foo { get; set; }
But in some cases, it can be a good idea:
private List<string> someStrings = null;
public List<string> SomeStrings {
get {
if (someStrings == null)
someStrings = new List<string>();
return someStrings;
}
}
public bool HasSomeStrings {
get { return (someStrings != null && someStrings.Count > 0); }
}
I'm really trying to figure out the best practices for reusable code that is easily debugged. I have ran into a common practice among developers that I don't quite understand yet.
public MyConstructor(Object myObject)
{
if (myObject == null)
throw new ArgumentNullException("myObject is null.");
_myObject = myObject;
}
It almost seems unnecessary to do this check. But I think it's because I don't completely understand what the benefits of doing this check are. It seems like a null reference exception would be thrown anyway? I am probably wrong, would really like to hear some thoughts on it.
Thank you.
To the compiler, null is a legitimate constructor argument.
Your class might be able to handle a null value for myObject. But if it can't - if your class will break when myObject is null - then checking in the constructor allows you to fail fast.
Passing a null object is perfectly legal in many cases - for this class the implementor wants to ensure that you cannot create an instance of the class w/o passing a valid Object instance though, so there have to be no checks later on - it's a good practice to ensure this as early as possible, which would be in the constructor.
if you under 4.0 you can do the following:
public ctor(IEnjection ninjaWeapon)
{
Contract.Requires<ArgumentNullException>(ninjaWeapon != null);
this.deadlyWeaponary.Add(ninjaWeapon);
}
if you under an older version, reference the Microsoft.Contract to do the same thing.
Others have already correctly stated that the passing of a null parameter may or may not be valid depending upon the functionality of the consuming code.
Where a null parameter is undesirable it is possible, from C# 7.0, to use throw expressions which allow us to rewrite null checking code much more succinctly as the following example shows:
public MyConstructor(Object myObject)
{
_myObject = myObject ?? throw new ArgumentNullException(nameof(myObject));
}
The above will set the value of _myObject to the parameter myObject unless that parameter is null, in which case an ArgumentNullException will be thrown.
The compilier has no idea about the value of an object, so you have to check this at runtime to ensure it doesn't get called with a null value.
It also depends on your particular solution. You don't need to throw the exception, I would only throw it if you can not have that value be null, and if it is null, that is an exceptional case.
I think that it is not possible to tell generally whether checking for null is necessary or not. It rather depends on whether you can live with null valued variables or not. Null is not per se a bad state. You might have situations where it is allowed for a variable to be null and other where it is not.
Ask yourself whether it makes sense to allow null values or not and design the constructor accordingly.
You could implement a simple ThrowIfNull extension method to reduce the code you write each time. Jon Skeet covered this in his blog and the referenced SO article here.
You need to explicitly check for null because the compiler doesn't know, but also because null can be a valid argument.
The benefit is that the exception will be thrown at the time of object construction, so you can easily trace which part of code is the culprit. If your code requires non-null myobject value and you don't validate it in the constructor, the NullReferenceException will be thrown when you use myObject_ and you will have to trace back manually to see who sent that null value in.