Validate null object - c#

In order to validate if model comes null or not I use something like this:
if (model is null || !model.Any()) return this;
But in latest Microsoft conference I saw guys use something like:
if(model is { })
I try to use it but always return true (if object comes null or not)
So my question is. Is there a new way to check if a model comes null?
What is the correct usage of brackets { }
Note: I googled about that brackets but I found anything. Regards

You can do a generic extension method to check if your object is null or not.
Try:
public static bool IsNullOrEmpty<T>(this IEnumerable<T> source) {
return source?.Any() != true;
}

Another way to check for NullOrEmpty is to coerce Count() to an int?. Then we can compare the result of GetValueOrDefault to 0:
if((model?.Count).GetValueOrDefault() == 0) return this;
How it works:
Because the ?. operator will return null if the left side is null, and Count returns an int, the result of (model?.Count) is a Nullable<int>.
The GetValueOrDefault method returns the value of Count if model is not null, otherwise it returns default(int) (which is 0).
This way if model is null, the condition returns 0

Related

What does Return myVar != null actually mean?

Resharper is a great tool, but it sometimes confuses me as to what the suggested code really means. I have this code:
private bool DoesUserExists()
{
var user = De.Users.FirstOrDefault(u => u.Username == CurrentUser.Username);
return user != null;
}
I originally had :
if(user == null)
return false;
else
return true;
But Resharper suggested the top code. However, that looks to me to be saying return user if it is not null. But the method only accepts a bool return and not a class.
So what does return user != null actually return when it is null and when it is not?
So what does return user != null actually return when it is null and
when it is not
It simply evaluates the expression. If user is null it returns false and if user isn't null, it returns true.
Think of this as if you were assigning the result of the comparison to a local variable, and only then returning it:
bool isNotNull = user != null;
return isNotNull;
Or:
bool isNull = user == null;
return !isNull;
isNotNull would be true only iff the user variable is not null.
Semantically, it is identical to your if-else statement.
Not sure I'm adding any value here, #Yuval's answer is correct and clear, but maybe it helps to see it this way.
You are thinking of parsing the code something like this:
(return user) (!= null)
That is, you see "return user" and wonder what the rest of the line is doing there. But return doesn't work that way. It evaluates the rest of the line, and returns that. It's more like
(return) (everything else)
or, in the specific case
(return) (user != null)
Where return gets executed last.
It is much like operator precedence, where 3+5*2 must be evaluated as 3+10 instead of 8*2, because * has higher precedence (must be evaluated first) than +. return has the lowest precedence of all.
If you learn to read and write code with this in mind, you will find yourself appreciating the refactored code.

Setting DateTime property to null

So I have this property and would like to either set the value to what is coming back from the db or to null if it is empty. It is possible to do this with an if-else, but for cleaner code, I would like to use the ternary operator. Could someone point out the mistake I am making. Thanks!!!
public DateTime? OptionExpiration {get;set;}
//actually sets the value to null
if(String.IsNullOrEmpty(dr["OPTION_EXPIRATION"].ToString())){
OptionExpiration = null;
}else{
OptionExpiration = DateTime.Parse(dr["OPTION_EXPIRATION"].ToString());
}
//so I check the to see if the string is empty or null, then try to set the value but recieve this error: Error 2 Operator '|' cannot be applied to operands of type '' and 'System.DateTime?'
String.IsNullOrEmpty(dr["OPTION_EXPIRATION"].ToString())
? OptionExpiration = null
| OptionExpiration = DateTime.Parse(dr["OPTION_EXPIRATION"].ToString())
;
You are using the ternary operator wrong.
It should be:
OptionExpiration = String.IsNullOrEmpty(Convert.ToString(dr["OPTION_EXPIRATION"]))
? (DateTime?)null
: DateTime.Parse(dr["OPTION_EXPIRATION"].ToString())
;
So:
assignment = condition ? trueExpression : falseExpression;
If the field is a date in your database, it might be better to do this:
OptionExpiration = Convert.IsDBNull(dr["OPTION_EXPIRATION"])
? (DateTime?)null
: (DateTime)dr["OPTION_EXPIRATION"]
;
I would use an extension method like this:
public static Nullable<DateTime> AsNullableDateTime(this object item, Nullable<DateTime> defaultDateTime = null)
{
if (item == null || string.IsNullOrEmpty(item.ToString()))
return defaultDateTime;
DateTime result;
if (!DateTime.TryParse(item.ToString(), out result))
return defaultDateTime;
return result;
}
You can pass anything in to this and it will attempt to give you back a date. If it fails for whatever reason (this also checks to make sure the object you send through is not null) you will get a null back; which is fine because you're mapping to a nullable datetime.
To use this you would do something like:
OptionExpiration = dr["OPTION_EXPIRATION"].AsNullableDateTime();
No mess, easy to understand what is happening, abstracting away the clutter, and highly reusable on other parts of your solution.

IsNull() extention for checking null value for any object

I am adding new extension method for checking null value for any object on following criteria:
Should return true if value for class object is null
Should return true if object is of type string and having value null or Empty
Should return true if object is of type DateTime and having Min value.
Any other condition for null need to check.(Please suggest if required.)
Here is IsNull() extention method:
public static bool IsNull(this object obj)
{
if (obj == null || obj == DBNull.Value)
return true;
if (obj.GetType() == typeof(string))
return string.IsNullOrEmpty(obj.ToString());
if (obj.GetType() == typeof(DateTime))
{
DateTime _dateValue = DateTime.MinValue;
if (DateTime.TryParse(obj.ToString(), out _dateValue) && _dateValue == DateTime.MinValue)
return true;
}
return false;
}
Now my question is:
Do I need to add check differently for Value and Reference type
object?
Does this extension method handle all type of null check for any
object?
Any suggestion or improvement need to add in extension?
Do I need to add check differenty for Value and Reference type object?
Value types can not be null.
Does this externtion method handle all type of null check for any object?
It looks like (except value types)
Any suggestion or improvement need to add in extention?
As I said value types cannot be null, so you can add an extra condition to check whether the type is value type or not,if so you can return false
if(obj.GetType().IsValueType) return false;
By the way if you write this before the DateTime check,your DateTime condition will become unreachable.It doesn't make sense anyway but it's your choice.If you want to return true when the value equals to DateTime.MinValue it's completely up to you.
A few observations:
1) A value type will never be null. When called on a value type.. it will be boxed to an object.. and won't be null (unless you wrap it in a Nullable<T>).
2) Your method no longer checks for null.. it also checks for a minimum value and empty strings. An empty string is not null - its an empty value. A minimum value is not null.. its a value. It has too much responsibility here and should be renamed.
3) Given what I've said above.. you could just simply do this instead of writing your own function:
if (variable == default(variable.GetType()))
Since that checks for the default of all types.. value types such as DateTime, int, and classes for null. Then, your only other specific check is for DBNull.Value.

How to cater for an object which can be both null or empty

I've got an object, specifically the following:
table.ExtendedProperties["MS_Description"].Value
If there is not property, the Value is null. If there is a property, but it is empty, the Value.toString() is "".
I would thus like to create an if-statement which caters for both eventualities. This is what I've done so far:
if (table.ExtendedProperties["MS_Description"] == null ||
table.ExtendedProperties["MS_Description"].Value.ToString().Equals(""))
The problem is that if it is null, it is still checking the condition on the right-hand-side.
Any ideas?
You can do:
if (table.ExtendedProperties["MS_Description"] == null || string.IsNullOrEmpty(table.ExtendedProperties["MS_Description"].Value))
The reason your code errors is because you don't check if table.ExtendedProperties["MS_Description"].Value is null.
Thus Value is not a string, then you have to deal with all conditions:
var description = table.ExtendedProperties["MS_Description"];
if (description == null ||
description.Value == null ||
description.Value.ToString().Equals(""))
// no value
BTW your code is not quite correct
if (table.ExtendedProperties["MS_Description"] == null ||
table.ExtendedProperties["MS_Description"].Value.ToString().Equals(""))
Instead of checking Value for null, you are checking if table.ExtendedProperties["MS_Description"] is not null. Thats true. You go further, but if table.ExtendedProperties["MS_Description"].Value is null (you didn't check that, remember?), you will get NullReferenceException on applying ToString().
I'm not sure if you are referring to the DataTable.ExtendedProperties property or something else, but if you are, the property returns a System.Data.PropertyCollection, which inherits from System.Collections.HashTable.
Most of the methods and properties, including the indexer ("Item") being discussed here, are directly inherited from HashTable, so in general, table.ExtendedProperties[key] can return any object, including null.
Note that you can also call DataTable.ExtendedProperties.ContainsKey(object key) to determine if the PropertyCollection contains a specific key or not.
Do you know what type of object you are retrieving when you call table.ExtendedProperties["MS_Description"].Value ?
If so, there might be other properties you can use to determine whether the property has been set, etc.
Depending on what type of object table.ExtendedProperties["MS_Description"] is, you might even be able to do something like this:
if ((table.ExtendedProperties["MS_Description"] ?? "").ToString().Length == 0) {
.....
}
That would take into account all of the possibilities:
the key doesn't exist
the key exists, but the value is null
the key exists and the value is empty
as long as the table.ExtendedProperties["MS_Decription"] object returns "" when its Value property is either null or empty.
So a little more information on the object that is returned could go a long way!
string.IsNullOrEmpty(table.ExtendedProperties["MS_Description"].Value)
It looks like table.ExtendedProperties["MS_Description"] is never null, you should be null checking the Value property instead
string value = table.ExtendedProperties["MS_Description"].Value;
if (value == null || value.ToString().Equals(""))
// OR
if (String.IsNullOrEmpty(value))
If table.ExtendedProperties["MS_Description"] can return null, then you need
if (table.ExtendedProperties["MS_Description"] == null ||
String.IsNullOrEmpty(table.ExtendedProperties["MS_Description"].Value.ToString() )
And since table.ExtendedProperties["MS_Description"].Value may return null, then you need
if (table.ExtendedProperties["MS_Description"] == null ||
table.ExtendedProperties["MS_Description"].Value == null ||
String.IsNullOrEmpty(table.ExtendedProperties["MS_Description"].Value.ToString() )

C# bool value as string is always null

I'm attempting to dump variable property information to a simple string but when it gets to my nullable bools, the as string always returns null --even if the actual value is true | false!
StringBuilder propertyDump = new StringBuilder();
foreach(PropertyInfo property in typeof(MyClass).GetProperties())
{
propertyDump.Append(property.Name)
.Append(":")
.Append(property.GetValue(myClassInstance, null) as string);
}
return propertyDump.ToString();
No exceptions are thrown; quick and the output is exactly what I want except any properties that are bool? are always false. If I quick watch and do .ToString() it works! But I can't guarantee other properties are not, in fact, null.
Can anyone explain why this is? and even better, a workaround?
A bool is not a string, so the as operator returns null when you pass it a boxed boolean.
In your case, you could use something like:
object value = property.GetValue(myClassInstance, null);
propertyDump.Append(property.Name)
.Append(":")
.Append(value == null ? "null" : value.ToString());
If you want to have null values just not append any text, you can just use Append(Object) directly:
propertyDump.Append(property.Name)
.Append(":")
.Append(property.GetValue(myClassInstance, null));
This will work, but leave null properties in your "propertyDump" output as missing entries.
The as operator returns a casted value if the instance is of that exact type, or null otherwise.
Instead, you just should .Append(property.GetValue(...)); Append() will automatically handle nulls and conversions.
The nicest solution would be, in my opinion:
.Append(property.GetValue(myClassInstance, null) ?? "null");
If the value is null, it will append "null", and if not - it will call the value's ToString and append that.
Combining that with Linq instead of a foreach loop, you can have a nice little something:
var propertyDump =
string.Join(Environment.NewLine,
typeof(myClass).GetProperties().Select(
pi => string.Format("{0}: {1}",
pi.Name,
pi.GetValue(myClassInstance, null) ?? "null")));
(Looks nicer in the wide screen of VS).
If you compare speeds, by the way, it turns out the string.Join is faster than Appending to a StringBuilder, so I thought you might want to see this solution.
That's because the type of the property is not string. Change it to:
Convert.ToString(property.GetValue(myClassInstance, null))
If it's null, it will retrieve null and that's ok. For non-null values it will return the string representation of the value of the property.
You cannot cast a bool to a string. You must use ToString()
Use the null coalesing operator to handle the Null situations:
void Main()
{
TestIt tbTrue = new TestIt() { BValue = true }; // Comment out assignment to see null
var result =
tbTrue.GetType()
.GetProperties()
.FirstOrDefault( prp => prp.Name == "BValue" )
.GetValue( tb, null ) ?? false.ToString();
Console.WriteLine ( result ); // True
}
public class TestIt
{
public bool? BValue { get; set; }
}

Categories