Do null objects always have to be specified in latest c# code? - c#

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?

Related

Code Optimisation - remove this expression which always evaluates to "true"

I am trying to optimize the code using SonarQube
List<string> itemList = serviceObject.GetItems();
I tried to validate the list with the below code
if(itemList != null && itemList.Any()
{
//Some operations
}
when above code executed I am getting Sonarqube error remove this expression which always evaluates to "true"
So I refactor the code as
if(itemList == null || !itemList.Any())
return;
//Some Operations
when above code executed I am getting Sonarqube error remove this expression which always evaluates to "false"
Could anyone let me know what is wrong here?
You can shorten this to
if (itemList?.Count >0)
{
...
}
or
if (itemList?.Any() ==true)
{
...
}
?. is one of the Null conditional operators (the other is ?[]), the Elvis operator for short, that allows you to access potentially null variables without throwing. The result of the entire expression after the Elvis operator is nullable and returns null if the variable is null.
This means that itemList?.Count returns an Nullable<int>, and itemList?.Any() a Nullable<bool>. Nullable<T> defines relational operators between itself and its base type T but can't be used as T without an explicit cast. That's why (itemList?.Any() ==true) is needed.
If you use Nullable Reference Types though, itemList can't be null, so a simple comparison would be enough:
if (itemList.Count >0)
{
...
}
If you enable Nullable Reference Types by setting #nullable enable in a source file or <Nullable>enable</Nullable> in the csproj file, the compiler ensures that all variables, fields and methods that return reference types are not null, forcing you to either fix the problem or explicitly specify that a variable is nullable.
With NRTs enabled this line :
List<string> itemList = serviceObject.GetItems();
Would only compile without warnings if GetItems never returned a null. If the compiler doubts this, it would issue a warning advising you to either fix the problem or explicitly declare itemList as nullable with :
List<string>? itemList = serviceObject.GetItems();
I believe it is due to null Comparision.
itemList != null
There is a high chance that serviceObject.GetItems(); is guaranteed to not return null by having a [NotNull] Annotation. Hence the null check is redundant.
How can I show that a method will never return null (Design by contract) in C#
if( itemList !=null ) {//Do something...}
List<string> itemList = new List<string>();
itemList = serviceObject.GetItems();
if(itemList!=null && itemList.Count() > 0 )
{
//Some operations
}
Count is enough to validate a list
List will always not be null but will have no elements. but you have to instatiate it so it wont throw an exception.

Custom null assertion in JetBrains Rider

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!

How to check if deserealized class members have value?

I have an initial snippet which deserealized parameters, checks for value and handles the error:
var param = js.Deserialize<int?>(jqData.Params);
if (param.HasValue)
{
resp.ReturnValue = param.Value;
}
else
{
//handle error code
}
Now, during my modification, I have changed the method to accept a list of class parameters instead of nullable integers
var param = js.Deserialize<ClassName>(jqData.Params);
Now it invalidates .HasValue and .Value methods.
My question is: How do I properly modify these two lines so it would hold the same meaning as initial if statement?
Thus far I only thought about switching to if (param != null), but I cannot think of proper equivalent to .Value.
As soon as ClassName is a class (see - a reference type) you just need to check if it is not null.
If it is not - then the variable holds a reference to an object that you use as-is.

Using a method for a null class

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!

Code Contracts warning about possibly failing 'Assume' call

In a class of mine, I have a private field of type ExpandoObject. The field is initialized in the constructior (this.expected = new ExpandoObject()), so I'm confident that it will never be null.
Thus, in one of the methods on this class, I fell safe to add
Contract.Assumes(this.expected != null)
before using this.expected for anything, so Code Contracts won't have to worry about possible calls on null objects. However, instead of a warning for possible method call on a null reference, I get a warning saying
The dynamically dispatched call to method 'Assume' may fail at runtime because one or more applicable overloads are conditional method
The method signature and the first few lines of code looks like this:
protected void Expect(object values)
{
Contract.Requires<ArgumentNullException>(values != null);
Contract.Assume(this.expected != null);
var exp = (ICollection<KeyValuePair<string, object>>)this.expected;
On the third line, I get a warning for
CodeContracts: Possibly calling a method on a null reference 'OddEnds.Testing.TestBase.o_SiteContainer0.<>p_Site3.Target'
where I assume the odd signature of the null reference is because exp is a dynamic object.
How do I solve these?
I think the best way to solve your problem is to declare that expected is never null as an invariant on the class:
class TheClass {
ExpandoObject expected;
...
[ContractInvariantMethod]
void Invariants()
{
Contract.Invariant(this.expected != null);
}
...
}
When you do this, the static checker will check that expected is not null at the end of your constructor, and then it will know that expected is never null at the start of any other method.
Im thinking following code change will keep compiler happy (if your sure in this cast anyway, but why use expandoobject then.. anyway)
ICollection<KeyValuePair<string, object>> col = this.expected as ICollection<KeyValuePair<string, object>>;
Contract.Assume(col != null);

Categories