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.
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
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
I'm attempting to understand the syntax of a piece of code someone else wrote.
The method is returning a bool, and the return statement looks like this:
return user.UserStatus == Models.User.UserStatuses.Inactive && user.IsLocked;
UserStatuses is a enum.
So it appears to me it returns the property of object user called UserStatus, however UserStatus is an enum, not a bool, and then && adds the bool as user.IsLocked, where is a bool.
I can't seem to understand how this is legal in c#, since it appears to return two parameters.
Add some parenthesis, or separate your line into multiple statements, and it makes sense. The compiler is just doing it for you (more or less). Your statement is equivalent to:
return ((user.UserStatus == Models.User.UserStatuses.Inactive) && user.IsLocked);
or
bool inactive = user.UserStatus == Models.User.UserStatuses.Inactive;
bool inactiveAndLocked = inactive && user.isLocked;
return inactiveAndLocked;
The key here is that return is taking an expression (not a parameter) and using the result of that expression, which is just one "thing" as the C# spec dictates.
bool result = (user.UserStatus == Models.User.UserStatuses.Inactive) &&
user.IsLocked;
return result;
It is just returning a boolean condition. Hypothetically, you could also check that same code on a IF statement like:
if(user.UserStatus == Models.User.UserStatuses.Inactive && user.IsLocked)
UserStatus is an enum but the base type of an enum is int. This is compared to the specific enum type. So the first part is basically (int == int) which yields a bool. The bool is then conditionally and'ed with the IsLocked value (bool && bool) to yield the final result.
Right now I am working on a simple program, and this is a problem I've been thinking over many times. Many times I run my methods twice because of checking on the return value before running them, and I would like to know if there is a way I can prevent this, like using the returned value from the method I am checking against. It's quite hard to explain so here is a real life example from my program.
public class SFDBRepository
{
public static Domain.SF.SFObject GetSFOrder(string WorkOrd)
{
//As you can see here i'm checking on the output of this method, before trying to return it.
if (Domain.SF.SF.GetOrder(WorkOrd) != null)
{
//If the value is not null (My method returns null if no result), return the object
return Domain.SF.SF.GetOrder(WorkOrd);
}
//Same thing happens here. My method runs twice every time almost.
else if(Domain.Building_DeliveryPerformance.Building_DeliveryPerformance.GetObject(WorkOrd) != null)
{
return Domain.Building_DeliveryPerformance.Building_DeliveryPerformance.GetObject(WorkOrd);
}
else
{
return null;
}
}
}
You can simplify this down to the following code, which will only call those methods once and make the code much more readable:
public class ShopFloorDBRepository
{
public static Domain.ShopFloor.ShopFloorObject GetShopFloorOrder(string workOrd)
{
return Domain.ShopFloor.Shopfloor.GetOrder(workOrd) ??
Domain.DG9_DeliveryPerformance.DG9_DeliveryPerformance.GetObject(workOrd);
}
}
To explain why this works - the ?? operator (the null-coalescing operator!) basically says "if the returned value on the left hand side of the ?? is null, then return the value of the expression on the right hand side".
This way you only need to call your functions once.
public static Domain.ShopFloor.ShopFloorObject GetShopFloorOrder(string WorkOrd)
{
//As you can see here i'm checking on the output of this method, before trying to return it.
Domain.ShopFloor.ShopFloorObject wo = Domain.ShopFloor.Shopfloor.GetOrder(WorkOrd);
if (wo != null)
{
//If the value is not null (My method returns null if no result), return the object
return wo;
}
//Same thing happens here. My method runs twice every time almost.
Domain.ShopFloor.ShopFloorObject yowo = Domain.DG9_DeliveryPerformance.DG9_DeliveryPerformance.GetObject(WorkOrd);
if(yowo != null)
{
return yowo;
}
/* default return */
return null;
}
PS
You're kinda doing the "Factory Pattern"
See
http://www.dofactory.com/net/factory-method-design-pattern
Looks to me like you could be using a temporary variable to hold the result, which you can test and return.
public class ShopFloorDBRepository
{
public static Domain.ShopFloor.ShopFloorObject GetShopFloorOrder(string WorkOrd)
{
var result = Domain.ShopFloor.GetOrder(WorkOrd);
if (result != null) return result;
...
This is a common paradigm, especially when the method being called is expensive and/or has side effects you don't wish to incur twice.
Here, the "var" declaration sets the type of "result" to the type returned by the method being called; you could also use the name of the actual type.
If you wish to make two different kinds of tests like this, you'll need two different variables unless they have the same type (which in this case it appears they do).
An alternate mechanism that does require the full type, that you'll also see:
public static ShopFloorObject GetShopFloorOrder(string WorkOrd)
{
ShopFloorObject result;
if ( (result = Domain.ShopFloor.GetOrder(WorkOrd)) != null )
return result;
if ( (result = Domain.DG9_DeliveryPerformance.DG9_DeliveryPerformance.GetObject(WorkOrd)) != null)
return result;
return null;
Here you're explicitly declaring the type of the return value, then making the two calls you've indicated, testing the results against null, and returning the first non-null value.
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.