I apologize if this question is a bit obsessive but I do like my code not to have any wiggly lines underneath it where resharper is telling me off.
I have a generic list:
var permissions = new List<Permission>();
at some point in the code I need to test the first element:
if (permissions.First().ImportID == this.ImportId)
{
// do stuff
}
Resharper (rightly) complains that permissions could be null, so I take its advice and add a check in:
if (permissions != null && permissions.First().ImportID == this.ImportId)
{
// do stuff
}
Now I realise that I need to protect against the list being empty so I add a check for any in there too:
if (permissions != null && permissions.Any() && permissions.First().ImportID == this.ImportId)
{
// do stuff
}
and life is good, the code works & resharper is quiet. Realising that the null + any() check is going to be used quite often I add an extension method:
public static bool IsEmpty<T>(this IEnumerable<T> source)
{
if (source == null)
return true;
return !source.Any();
}
The only problem is now when I use this:
if (!permissions.IsEmpty() && permissions.First().ImportID == this.ImportId)
Resharper starts moaning again "Possible null assignment to entity marked with "NotNull" attribute".
So, is there a way to let resharper know that permissions will never be null after IsEmpty() has executed (in the same way it understands what != null does) or is my only option to ignore the message.
I suspect you can use a R# annotation for this. Something like:
[ContractAnnotation("null => true")]
public static bool IsEmpty<T>(this IEnumerable<T> source)
{
return source == null || !source.Any();
}
I believe that should give R# enough information to work out that you're not trying to use a null reference if IsEmpty returns false.
Related
I have a relatively simple extension method called TryGetFirst
public static bool TryGetFirst<T>(this IList<T> list, out T value)
{
if (list == null || list.Count == 0)
{
value = default;
return false;
}
value = list[0];
return true;
}
It does a few things at once. It null checks the list, checks if the list is empty, and if not, returns the first element. Kind of like Linq's FirstOrDefault but with a built in null check. Nothing too fancy.
I'm looking for the correct ContractAnnotation syntax to communicate the following facts to ReSharper, but I can't seem to nail them all down.
If the list is null, always return false
If the return value is true, the list is not null
If the return value is false, the value is null
Given the following code I expect the following ReSharper hints, at least in Pessimistic Value Analysis Mode in Rider
if (StringExtensions.TryGetFirst<object>(null, out object value) { ... } // Expression is Always False
if (_possiblyNullList.TryGetFirst<object>(out object value)
{
_possiblyNullList.DoSomething(); // No Warning
value.DoSomething(); // Possible NullReferenceException
}
else
{
_possiblyNullList.DoSomething(); //Possible NullReferenceException
if (value == null) { ... } // Expression is Always True
}
At first I tried [ContractAnnotation("list:null => false; => false, value:null")] but for some reason ReSharper interpreted that as all code paths always return false and therefore the contents of the if { ... } were unreachable.
Next I tried [ContractAnnotation("list:null => false; => false, value:null; => true")] as I thought adding the true case on the end would inform ReSharper that a true result was possible. This is slightly better, but the _possiblyNullList.DoSomething(); inside the if block was being marked as a possible NullReference and StringExtensions.TryGetFirst<object>(null, ... was no longer marked as Always False.
The closest I've been able to get to my target is [ContractAnnotation("=> true, list:notnull, value:canbenull; => false, list:canbenull, value:null")] which handles every case except for StringExtensions.TryGetFirst<object>(null, ... which doesn't get marked as Always False. I tried adding back the list:null => false line but it made no difference. I also feel like this syntax is a lot more verbose than seems necessary, but I'm willing to live with it if it's accurate.
I feel like I've run out of permutations to try. Is this just a case that isn't supported by the attribute or am I missing something obvious?
Try this:
list:null => false,value:null;list:notnull=>false,value:null;list:notnull=>true,value:canbenull
I have a custom extension method for checking Guid? values:
public static bool IsNullOrDefault(this Guid? guid)
{
return !guid.HasValue || guid.value == Guid.Empty;
}
When I use the method in my code, I would expect that Rider will consider this method in possible System.InvalidOperationException assertions. But it does not.
public void Foo(Guid? guid)
{
if (guid.IsNullOrDefault())
{
throw new Exception();
}
var x = guid.Value;
^ There is still a yellow squiggle here, saying Possible System.InvalidOperationException
...
}
I have tried creating my own Null Checking pattern by overwriting the Custom (statement) pattern:
if ($EXPR$.IsNullOrDefault()) throw new System.ArgumentNullException($NAME$);
But that does not work either. How can I configure Rider to consider my custom method an equivalent to guid.HasValue or guid != null?
I'm not sure Rider is intelligent enough to recognize that you already checked this.
I think what you can do instead, is use the ?. notation to check for null
var x = guid?.Value;
This check if guid is null before the .value is evaluated, and just return null if that's the case.
Then you can put the check afterward instead, so it ends up like
var x guid?.value;
if(x is null)
Throw new Exception();
Or you can return a default value instead of throwing an exception, your call.
Let me know how it works!
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.
I've ran into an issue where code classes outside of my control use strings that are null so when they become referenced for example, "string.Length", causes an error. Rather than write a check for the possible 100 fields on average, with nested classes, I thought maybe I could create something easier. I had an idea...
If you've done any research into copying objects PropertyCopy, along with a few others, is an extremely common find. I currently use the class mentioned above. I was wondering if it could be modified to simply go:
if stringPropertyValue is null then set stringPropertyValue equal to string.Empty.
My understanding is limited. I've been doing research to solve my issue but no real good ideas. Can my idea work? Is there a better way? How would it be done if it could?
Update:
Based on a response below I have created this class which I am currently going to use.
public static void DenullifyStringsToEmpty<T>(this T instance)
{
//handle properties
foreach (var filteredProperties in instance.GetType().GetProperties().Where(p =>
(p.PropertyType.IsClass || p.PropertyType.IsInterface || p.PropertyType == typeof(string))))
{
if (filteredProperties.PropertyType == typeof(string))
{
if (filteredProperties.GetValue(instance, null) == null)
{
filteredProperties.SetValue(instance, string.Empty, null);
}
}
else
{
filteredProperties.GetValue(instance, null).DenullifyStringsToEmpty();
}
}
//handle fields
foreach (var filteredFields in instance.GetType().GetFields().Where(f =>
(f.FieldType.IsClass || f.FieldType.IsInterface || f.FieldType == typeof(string))))
{
if (filteredFields.FieldType == typeof(string))
{
if (filteredFields.GetValue(instance) == null)
{
filteredFields.SetValue(instance, string.Empty);
}
}
else
{
filteredFields.GetValue(instance).DenullifyStringsToEmpty();
}
}
}
I know that reflection can be heavy and until we have an issue I think this solution will work great. This is an extension (thanks to the comments below).
Thanks for the input.
Couldn't you just create a simple extension method?
public static string NullToEmpty(this string possibleNullString)
{
return possibleNullString ?? string.Empty;
}
Use this, when accessing the string properties of that third party classes, e.g.:
var length = instanceOfThirdPartyClass.StringProperty.NullToEmpty().Length;
Update:
Now that I understand what you want ;-)
Have a look at this:
public static void DenullStringProperties<T>(this T instance)
{
foreach(var propertyInfo in instance.GetType().GetProperties().
Where(p => p.PropertyType == typeof(string))
{
var value = propertyInfo.GetValue(instance, null);
if(value == null)
value = string.Empty;
propertyInfo.SetValue(instance, value, null);
}
}
You could call it like this:
instanceOfThirdPartyClass.DenullStringProperties();
But I still think you should go with the first approach, because I really don't see a reason to do such heavy lifting during runtime (reflection isn't cheap), just because you are lazy about typing during development :) Additionally, you can't be sure that the properties will stay non null after you have called DenullStringProperties (multi-threading, calls to methods of the object, ...). The first approach checks for null and handles it just as it is needed.
This question already has answers here:
Best and fastest way to check if an object is null [duplicate]
(6 answers)
Closed 9 years ago.
What is the most efficient way to check for null references on objects? I have seen various code samples that have different ways of checking so of the following which is the most efficient or the one that it is considered best practice to use?
Object.ReferenceEquals(item, null)
item == null
item != null
Object.Equals(item, null)
thanks
Object.ReferenceEquals(item, null) compare references and equals to item == null.
Object.Equals(item, null) compare references for reference types and bitwise for value types, but in reflector it's equal to (item == null) || ((item != null && null != null) && item.Equals(null)).
item != null code not always equals to !(item == null), but of course result should be equal.
item == null code not equals to null == item, it's similar to typeof(item).Equals(object) and object.Equals(typeof(item)) method calls.
It differ because you can override !=, ==, Equals.
Use methods with known implementation, null == item is better to code, but harder to read.
Object.ReferenceEquals(null, item) may be faster or not.
P.S. use string.IsNullOrEmpty(item) too
For comparing to null, I'd use == or != always, because for null it should always give the same result as ReferenceEquals and Equals anyway (so no need for the extra code).
Edit: It's true that == could be overridden to give a wrong result for null (i.e., true) but that means the override is buggy. To make the code readable I would stick with == and !=.
Updated answer
As of C# 7.0 is you can use:
item is null
should be the simplest and most foolproof way. It's same as ReferenceEquals check.
Old answer:
1)
Object.ReferenceEquals(item, null)
This is a good way. Not as concise as I would love, but still great and tells u the intent exactly.
2)
item == null
item != null
There is nothing wrong with this (which is the most elegant) if you are sure == and subsequently != is overloaded correctly. Its easy to write (overload) bad equality operators (and often done). But the real trouble is when you are trying to overload == operator in a class (lets say of value semantic). You cant use == for null checks inside == overloading function of the class since that will cause an infinite recursion. To have one consistent style, I rely on something else.
3)
Object.Equals(item, null)
Again it internally does a ReferenceEquals so there is not much point, but if it semantically makes more sense to you, then go with this.
4)
My approach is to do
(object)item == null
upon which I'm relying on object's own equality operator which can't go wrong. Not so readable so I just wrap in a custom extension method and an overload:
public static bool IsNull<T>(this T obj) where T : class
{
return (object)obj == null;
}
public static bool IsNull<T>(this T? obj) where T : struct
{
return !obj.HasValue;
}
It makes more sense since I will need to check against DBNulls too often. So now I have one consistent style all over!
public static bool IsNull<T>(this T obj) where T : class
{
return (object)obj == null || obj == DBNull.Value;
}
(Do not take off the (object) casting as that's what will prevent infinite recursion when overloading == as stated before)
Additionally the constraint prevents IsNull on value types. Now its as sweet as calling
object obj = new object();
Guid? guid = null;
bool b = obj.IsNull(); // false
b = guid.IsNull(); // true
2.IsNull(); // error
I also have found (object)item == null is very very very slightly faster than Object.ReferenceEquals(item, null) or object.Equals(,) for that matter, but only if it matters (I'm currently working on something where I've to micro-optimize everything!).
To see a complete guide on implementing equality checks, see What is "Best Practice" For Comparing Two Instances of a Reference Type?
As an extra, don't forget code contracts in .NET 4.0!
System.Diagnostics.Contracts.Contract.Requires(item != null);
Which is not only nice and clear, but allows compile time checking. See Code Contracts in msdn.
ReferenceEquals is equivalent to (object)o1==(object)o2. It may be faster than o1==o2 if the equality operator is overloaded. Object.Equals is probably a bit slower.
The difference between == and != isn't performance, but how your program should look like. They can be a bit slower if the == and != operator are overloaded.
But I don't think the performance difference between them matters at all. I'd choose the one that's easiest to read. And that's usually == or !=.
If I throw an exception I usually use == as in:
if(o == null)
throw new ...;
If null results in a no-op then usually != is appropriate
if(x != null)
{
...
}
I always use
item != null
but this is harder to read than
item == null
Object.ReferenceEquals is used to check whether two objects are the same instance.
First 2 are the same effectively.
The last however does not only do a reference check, and should not be used for null checking.