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!
Related
Please consider the following code:
public IList<string> DoSomething(SomeModel model)
{
if (model == null)
{
return new List<string> {"model is null"};
}
...
}
When I wrote the above code I keep getting a suggestion from Resharper that says "Expression is always false"
But I don't understand why because the expression here can most definitely be true if I pass a null object.
Now consider me calling this method:
DoSomething(null);
Here I get a warning from resharper that says Cannot convert null literal to non-nullable reference type.
Is there some new change in c# code that I'm just simply not aware of? We have to explicitly now specify null objects and if so what is the new "null" value?
With C# 6.0 in the VS2015 preview we have a new operator, ?., which can be used like this:
public class A {
string PropertyOfA { get; set; }
}
...
var a = new A();
var foo = "bar";
if(a?.PropertyOfA != foo) {
//somecode
}
What exactly does it do?
It's the null conditional operator. It basically means:
"Evaluate the first operand; if that's null, stop, with a result of null. Otherwise, evaluate the second operand (as a member access of the first operand)."
In your example, the point is that if a is null, then a?.PropertyOfA will evaluate to null rather than throwing an exception - it will then compare that null reference with foo (using string's == overload), find they're not equal and execution will go into the body of the if statement.
In other words, it's like this:
string bar = (a == null ? null : a.PropertyOfA);
if (bar != foo)
{
...
}
... except that a is only evaluated once.
Note that this can change the type of the expression, too. For example, consider FileInfo.Length. That's a property of type long, but if you use it with the null conditional operator, you end up with an expression of type long?:
FileInfo fi = ...; // fi could be null
long? length = fi?.Length; // If fi is null, length will be null
It can be very useful when flattening a hierarchy and/or mapping objects. Instead of:
if (Model.Model2 == null
|| Model.Model2.Model3 == null
|| Model.Model2.Model3.Model4 == null
|| Model.Model2.Model3.Model4.Name == null)
{
mapped.Name = "N/A"
}
else
{
mapped.Name = Model.Model2.Model3.Model4.Name;
}
It can be written like (same logic as above)
mapped.Name = Model.Model2?.Model3?.Model4?.Name ?? "N/A";
DotNetFiddle.Net Working Example.
(the ?? or null-coalescing operator is different than the ? or null conditional operator).
It can also be used out side of assignment operators with Action. Instead of
Action<TValue> myAction = null;
if (myAction != null)
{
myAction(TValue);
}
It can be simplified to:
myAction?.Invoke(TValue);
DotNetFiddle Example:
using System;
public class Program
{
public static void Main()
{
Action<string> consoleWrite = null;
consoleWrite?.Invoke("Test 1");
consoleWrite = (s) => Console.WriteLine(s);
consoleWrite?.Invoke("Test 2");
}
}
Result:
Test 2
Basically, I have applied ?. operator after Model as well. I am trying to know that whether it can be applied directly to the model or does it only work with the navigation properties?
The ? or null conditional operator operators on the left value, regardless of the type of value. And the compiler doesn't care what the value is on the right. It's simple compiler magic (meaning it does something you can already do, just in a simplified why).
For example
var a = model?.Value;
is the same as saying
var a = model == null ? null : model.Value;
In the second case the evaluation of checking for null has no associate with the value returned. The null conditional operator basically just always return null if the left value is null.
The type of member (Method, Field, Property, Constructor) .Value is irrelevant.
The reason your DotNetFiddle example doesn't work is because the compiler being use for the .Net 4.7.2 isn't compatible with the c# version that support the null conditional operator. Changing it to .Net 5, works:
https://dotnetfiddle.net/7EWoO5
This is relatively new to C# which makes it easy for us to call the functions with respect to the null or non-null values in method chaining.
old way to achieve the same thing was:
var functionCaller = this.member;
if (functionCaller!= null)
functionCaller.someFunction(var someParam);
and now it has been made much easier with just:
member?.someFunction(var someParam);
I strongly recommend this doc page.
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.
Say I have a class
class T
{
int num;
public T(int num)
{
this.num = num;
}
public void p()
{
Console.WriteLine(this.num);
}
}
And I have a null object T t = null. Calling the method t.p() will cause a NullReferenceException no matter what.
Is it not possible to test if the object is null (by using this == null (to check if the object is null within the method)), so is there a way to set a default method that will work on a null object?
In whatever code that calls t.p() you should check if t is null. You shouldn't be calling methods on a null instance.
Regarding the second part of your question, no it is not possible to set a default method that will be called if the instance of that object is null.
I should point out that there is also the Null Object Pattern, that, depending on the exact circumstances of usage may help. I would not use it as replacement for null checks though. I've found the pattern useful in some cases.
In C/C++ you can do this, but not (easily) in C#.
For example, you might want to have a check for "if a string is empty" or "if a collection is empty", and treat a null object as meaning "empty". For this sort of case, being able to call an IsEmpty() method via a null pointer/reference results in what seems like more elegant/readable code:
if (myList.IsEmpty())
...
rather than
if (myList == null || myList.IsEmpty())
...
However, it is also extremely dangerous as it hides unusual/unexpected behaviour, and encourages the caller to stop checking for nulls. As you cannot guarantee that every method you call will protect you from nulls, how do you know that it is safe to stop checking for nulls in the calling code? Or do you check for null twice (in both the calling and called code), just in case? If you are calling many methods on the same object instance, wouldn't it be far more efficient to check for null once at the start?
So although this pattern can be used in some languages, it is not considered a good practice.
This is (one reason) why, in C#, such code is not allowed. Instead the preferred pattern is to provide a static method to check the status:
if (string.IsNullOrEmpty(myString))
....
This is only slightly less readable, but much safer as the null check is clearly visible to the reader. Even without "IsNull" in the title, tou can see that the reference is being passed to another method, and it is more reasonable to assume that the called method will be well written and check for nulls. Being transparent and explicit makes code much easier for others to read.
C# also provides the null coalescing ?? operator to make the null checks cleaner in the calling code. If you want a default to use if the object is null, then you can use this form:
string result = myString ?? string.Empty;
...which in this case will return myString if it is non-null, or string.Empty if it is null, thus guaranteeing that result is never null.
Finally, in C# 6 you can use the ?. operator, which combines an "if not null" check with an access, so you can replace:
if (element != null && element.FirstChild != null)
element.FirstChild.DoSomething();
with
element?.FirstChild?.DoSomething();
This is functionally equivalent, but a much more compact syntax.
Calling an instance method on a null reference will always result in a NullReferenceException. You have to check if the reference is not null or use the C# 6 ?. operator to do it for you.
T t = null;
t?.p(); // no method is called
You can however use an extension method on a null reference. It has some limitations, as you can only access public members in an extension method, but might be useful (especially if you cannot use C# 6 and ?.):
class T
{
public int Number { get; private set; } // public property
public T(int number)
{
Number = number;
}
}
static class Extensions
{
public static void PrintT(this T t)
{
if (t == null) Console.WriteLine("null");
else Console.WriteLine(t.Number);
}
}
T t = null;
t.PrintT(); // no exception, writes "null" to the console
It is possible to call an instance method on a null reference in CIL, simply using call instead of callvirt. The latter checks the run-time type of the referenced object, that's why it throws NRE immediately. call should call the method normally, but with the implicit this parameter set to null, and throw on first access to any member of this.
Edit
The System.Reflection.Emit namespace in C# contains types that let you dynamically emit IL. You can use it to call an instance method with a call instead of callvirt. (I modified code posted in this answer to work for methods. The sample here will only work for parameterless methods)
public static void MakeNonVirtualCall<T>(T c, Expression<Action<T>> f)
{
var expression = f.Body as MethodCallExpression;
if (expression == null) throw new ArgumentException();
var dyn = new DynamicMethod("NVCall", null, new[] { typeof(T) }, typeof(T).Module, true);
var il = dyn.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, expression.Method);
il.Emit(OpCodes.Ret);
((Action<T>)dyn.CreateDelegate(typeof(Action<T>)))(c);
}
Now, assuming we have a class
class Class
{
public void Method()
{
if (this == null) Console.WriteLine("`this` is null");
else Console.WriteLine("`this` is not null");
}
}
We can use it as
Class nullRef = null;
Class instance = new Class();
MakeNonVirtualCall(nullRef, t => t.Method()); // no exception, prints "`this` is null"
MakeNonVirtualCall(instance, t => t.Method()); // prints "`this` is not null"
It works - an instance method in a C# class can be called on a null reference from IL (but still not directly from C#).
Note that the MSDN documentation is incorrect here:
Calls to an instance (or virtual) method must push that instance reference before any of the user-visible arguments. The instance reference must not be a null reference.
Just check for null in the calling code.
T t = null;
// somewhere further..
if (t == null)
//t is null, don't use it
else
//save to use t
Another way (if you don't expect the object to be null is to use try/catch):
T t = null;
// somewhere further..
try {
t.p();
}
catch(NullReferenceException ex) {
// t is null
}
No you can't. And I'll tell you why. The keyword this refers to whichever object is accessing a variable or calling a method. So a this inside doSomething() would refer to object in object.doSomething().
Now coming to your question about null, when you write T t = null; it means you made a variable of type T which REFERS to NOTHING!!! And by nothing I mean, wait for it, NOTHING! Can you call methods from nothingness? NO!
I have a number of methods doing next:
var result = command.ExecuteScalar() as Int32?;
if(result.HasValue)
{
return result.Value;
}
else
{
throw new Exception(); // just an example, in my code I throw my own exception
}
I wish I could use operator ?? like this:
return command.ExecuteScalar() as Int32? ?? throw new Exception();
but it generates a compilation error.
Is it possible to rewrite my code or there is only one way to do that?
For C# 7
In C# 7, throw becomes an expression, so it's fine to use exactly the code described in the question.
For C# 6 and earlier
You can't do that directly in C# 6 and earlier - the second operand of ?? needs to be an expression, not a throw statement.
There are a few alternatives if you're really just trying to find an option which is concise:
You could write:
public static T ThrowException<T>()
{
throw new Exception(); // Could pass this in
}
And then:
return command.ExecuteScalar() as int? ?? ThrowException<int?>();
I really don't recommend that you do that though... it's pretty horrible and unidiomatic.
How about an extension method:
public static T ThrowIfNull(this T value)
{
if (value == null)
{
throw new Exception(); // Use a better exception of course
}
return value;
}
Then:
return (command.ExecuteScalar() as int?).ThrowIfNull();
Yet another alternative (again an extension method):
public static T? CastOrThrow<T>(this object x)
where T : struct
{
T? ret = x as T?;
if (ret == null)
{
throw new Exception(); // Again, get a better exception
}
return ret;
}
Call with:
return command.ExecuteScalar().CastOrThrow<int>();
It's somewhat ugly because you can't specify int? as the type argument...
As has been said, you can't do this with the ?? operator (well, not without some contortions that don't seem to fit with your aim of making this cleaner).
When I see this pattern emerging I immediately think of Enforcements. Originally from the C++ world they transfer to C# pretty well, although are arguably less important most of the time.
The idea is that you take something of the form:
if( condition )
{
throw Exception;
}
and converts it to:
Enforce<Exception>( condition );
(you can further simplify by defaulting the exception type).
Taking it further you can write a set of Nunit-style methods for different condition checks, e.g.;
Enforce<Exception>.NotNull( obj );
Enforce<Exception>.Equal( actual, expected );
Enforce<Exception>.NotEqual( actual, expected );
etc.
Or, better still by providing an expectation lamba:
Enforce<Exception>( actual, expectation );
What's really neat is that, once you've done that, you can return the the actual param and enforce inline:
return Enforce( command.ExecuteScalar() as Int32?, (o) => o.HasValue ).Value;
... and this seems to be the closest to what you're after.
I've knocked up an implementation of this before. There's a couple of little niggles, like how you generically create an exception object that takes arguments - some choices there (I chose reflection at the time, but passing a factory in as an extra parameter may be even better). But in general it's all pretty straightforward and can really clean up a lot of code.
It's on my list of things to do to knock up an open source implementation.
If you just want an exception when the returned value isn't an Int32 then do this:
return (int)command.ExecuteScalar();
If you want to throw your own custom exception then I'd probably do something like this instead:
int? result = command.ExecuteScalar() as int?;
if (result == null) throw new YourCustomException();
return result.Value;
You're not going to be able to throw an exception on the right side of the null coalescing operator. The reason behind this is that that the right side of the operator needs to be an expression, not a statement.
The null coalescing operator works like so: if the left value of the operator is null, return it; otherwise, return what's on the right of the operator. The throw keyword doesn't return a value; hence, it can't be used on the right side of the operator.
The reason you can't do:
return command.ExecuteScalar() as Int32? ?? throw new Exception();
Is because throwing an exception is a statement, not an expression.
If you're just looking to shorten the code a little bit, perhaps this:
var result = command.ExecuteScalar() as Int32?;
if(result.HasValue) return result;
throw new Exception();
No need for the else.