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
Related
This is a C# question specifically inside the Unity environment (which may or may not be relevant here).
I have a specific condition in a Property as follows:
public override bool IsFinished
{
get
{
return buildable == null || (buildable != null && buildable.BuildingComplete);
}
}
The buildable variable is an IBuildable, which in this case is a GameObject that has already been destroyed through the GameObject.Destroy method.
Now this condition should in this situation be true because the gameObject has been destroyed, and the buildable variable is already null. However in Unity when you destroy a gameObject, you can still access that object's properties, even though the buildable == null comparison returns true.
The problem is: even though buildable is actually null, the property returns false. Proof below:
Any ideas?
The default value for boolean is false. In debugging mode, when a line is highlighted, execution is not run over it yet. So, that line is not executed and that expression is not computed yet. Just change that return statement to:
var result = buildable == null || (buildable != null && buildable.BuildingComplete);
return result;
Then put a breakpoint to result line and inspect result when that breakpoint is hit.
Btw, as #gunr2171 pointed out in a comment, buildable != null is not needed in that expression.
Thanks guys for the quick answer. The == operator is overriden indeed in Unity for this particular one (and there's not much I can do about it because it's in the library itself).
I rewrote it so you can see, I understand that the default value of a boolean is false.
As you can see here, even though the buildable is null, it can still be evaluated and there are actually values inside it. The only thing I can't wrap my head around is that the left condition is STILL true (buildable == null evaluates as true) but the result is false.
Okay I just found out some legend has already found it out. It's because of Unity's operator overload, so here's the solution, I just tested and it works. Instead of using buildable == null, I'm using this method now and it works perfectly.
/// <summary>
/// Returns true if the object is either a null reference or has been destroyed by unity.
/// This will respect ISPDisposable over all else.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static bool IsNullOrDestroyed(this System.Object obj)
{
if (object.ReferenceEquals(obj, null)) return true;
if (obj is UnityEngine.Object) return (obj as UnityEngine.Object) == null;
return false;
}
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've got this code:
if (null == _priceComplianceSummaryList)
{
_priceComplianceSummaryList = new List<PriceComplianceSummary>();
}
Resharper flags it as an issue, suggesting, "Replace 'if' statement with respective branch" If I acquiesce, the code above changes to:
_priceComplianceSummaryList = new List<PriceComplianceSummary>();
Yet it seems R# is often more the belt-and-suspenders type of "cat," urging me to always check if something is null prior to referencing it. So is this ostensibly reckless behavior on its part really just a matter of efficiency? IOW, does "new List<>" only generate a new list if the istance variable (_priceComplianceSummaryList) is null, without having to explicitly check that?
"Replace 'if' statement with respective branch" R# suggestion means that there is no scenarios when your boolean expression returns false. For example,
void SomeMethod(bool firstParam)
{
var secondParam = true;
if (firstParam || secondParam)
{
Console.WriteLine();
}
}
This code will refactor by R# because firstParam || secondParam is always true.
Then, your 2 examples of code are not always equivalent, but in your scenario they are.
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.
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.