Mark parameters as NOT nullable in C#/.NET? - c#

Is there a simple attribute or data contract that I can assign to a function parameter that prevents null from being passed in C#/.NET? Ideally this would also check at compile time to make sure the literal null isn't being used anywhere for it and at run-time throw ArgumentNullException.
Currently I write something like ...
if (null == arg)
throw new ArgumentNullException("arg");
... for every argument that I expect to not be null.
On the same note, is there an opposite to Nullable<> whereby the following would fail:
NonNullable<string> s = null; // throw some kind of exception

There's nothing available at compile-time, unfortunately.
I have a bit of a hacky solution which I posted on my blog recently, which uses a new struct and conversions.
In .NET 4.0 with the Code Contracts stuff, life will be a lot nicer. It would still be quite nice to have actual language syntax and support around non-nullability, but the code contracts will help a lot.
I also have an extension method in MiscUtil called ThrowIfNull which makes it a bit simpler.
One final point - any reason for using "if (null == arg)" instead of "if (arg == null)"? I find the latter easier to read, and the problem the former solves in C doesn't apply to C#.

I know I'm incredibly late to this question, but I feel the answer will become relevant as the latest major iteration of C# comes closer to release, then released. In C# 8.0 a major change will occur, C# will assume all types are considered not null.
According to Mads Torgersen:
The problem is that null references are so useful. In C#, they are the
default value of every reference type. What else would the default
value be? What other value would a variable have, until you can decide
what else to assign to it? What other value could we pave a freshly
allocated array of references over with, until you get around to
filling it in?
Also, sometimes null is a sensible value in and of itself. Sometimes
you want to represent the fact that, say, a field doesn’t have a
value. That it’s ok to pass “nothing” for a parameter. The emphasis is
on sometimes, though. And herein lies another part of the problem:
Languages like C# don’t let you express whether a null right here is a
good idea or not.
So the resolution outlined by Mads, is:
We believe that it is more common to want a reference not to be null. Nullable reference types
would be the rarer kind (though we don’t have good data to tell us by
how much), so they are the ones that should require a new annotation.
The language already has a notion of – and a syntax for – nullable value types. The analogy between the two would make the language
addition conceptually easier, and linguistically simpler.
It seems right that you shouldn’t burden yourself or your consumer with cumbersome null values unless you’ve actively decided that you
want them. Nulls, not the absence of them, should be the thing that
you explicitly have to opt in to.
An example of the desired feature:
public class Person
{
public string Name { get; set; } // Not Null
public string? Address { get; set; } // May be Null
}
The preview is available for Visual Studio 2017, 15.5.4+ preview.

I know this is a VERY old question, but this one was missing here:
If you use ReSharper/Rider you may use the Annotated Framework.
Edit: I just got a random -1 for this answer. That's fine. Just be aware it is still valid, even though it's not the recommended approach for C#8.0+ projects anymore (to understand why, see Greg's answer).

Check out the validators in the enterprise library. You can do something like :
private MyType _someVariable = TenantType.None;
[NotNullValidator(MessageTemplate = "Some Variable can not be empty")]
public MyType SomeVariable {
get {
return _someVariable;
}
set {
_someVariable = value;
}
}
Then in your code when you want to validate it:
Microsoft.Practices.EnterpriseLibrary.Validation.Validator myValidator = ValidationFactory.CreateValidator<MyClass>();
ValidationResults vrInfo = InternalValidator.Validate(myObject);

not the prettiest but:
public static bool ContainsNullParameters(object[] methodParams)
{
return (from o in methodParams where o == null).Count() > 0;
}
you could get more creative in the ContainsNullParameters method too:
public static bool ContainsNullParameters(Dictionary<string, object> methodParams, out ArgumentNullException containsNullParameters)
{
var nullParams = from o in methodParams
where o.Value == null
select o;
bool paramsNull = nullParams.Count() > 0;
if (paramsNull)
{
StringBuilder sb = new StringBuilder();
foreach (var param in nullParams)
sb.Append(param.Key + " is null. ");
containsNullParameters = new ArgumentNullException(sb.ToString());
}
else
containsNullParameters = null;
return paramsNull;
}
of course you could use an interceptor or reflection but these are easy to follow/use with little overhead

Ok this reply is a bit late, but here is how I am solving it:
public static string Default(this string x)
{
return x ?? "";
}
Use this exension method then you can treat null and empty string as the same thing.
E.g.
if (model.Day.Default() == "")
{
//.. Do something to handle no Day ..
}
Not ideal I know as you have to remember to call default everywhere but it is one solution.

Related

Why do we get possible dereference null reference warning, when null reference does not seem to be possible?

Having read this question on HNQ, I went on to read about Nullable Reference Types in C# 8, and made some experiments.
I'm very aware that 9 times out of 10, or even more often, when someone says "I found a compiler bug!" this is actually by design, and their own misunderstanding. And since I started to look into this feature only today, clearly I do not have very good understanding of it. With this out of the way, lets look at this code:
#nullable enable
class Program
{
static void Main()
{
var s = "";
var b = s == null; // If you comment this line out, the warning on the line below disappears
var i = s.Length; // warning CS8602: Dereference of a possibly null reference
}
}
After reading the documentation I linked to above, I would expect the s == null line to give me a warning—after all s is clearly non-nullable, so comparing it to null does not make sense.
Instead, I'm getting a warning on the next line, and the warning says that s is possible a null reference, even though, for a human, it's obvious it is not.
More over, the warning is not displayed if we do not compare s to null.
I did some Googling and I hit a GitHub issue, which turned out to be about something else entirely, but in the process I had a conversation with a contributor that gave some more insight in this behaviour (e.g. "Null checks are often a useful way of telling the compiler to reset its prior inference about a variable's nullability."). This still left me with the main question unanswered, however.
Rather than creating a new GitHub issue, and potentially taking up the time of the incredibly busy project contributors, I'm putting this out to the community.
Could you please explain me what's going on and why? In particular, why no warnings are generated on the s == null line, and why do we have CS8602 when it does not seem like a null reference is possible here? If nullability inference is not bullet-proof, as the linked GitHub thread suggests, how can it go wrong? What would be some examples of that?
This is effectively a duplicate of the answer that #stuartd linked, so I'm not going to go into super deep details here. But the root of the matter is that this is neither a language bug nor a compiler bug, but it's intended behavior exactly as implemented. We track the null state of a variable. When you initially declare the variable, that state is NotNull because you explicitly initialize it with a value that is not null. But we don't track where that NotNull came from. This, for example, is effectively equivalent code:
#nullable enable
class Program
{
static void Main()
{
M("");
}
static void M(string s)
{
var b = s == null;
var i = s.Length; // warning CS8602: Dereference of a possibly null reference
}
}
In both cases, you explicitly test s for null. We take this as input to the flow analysis, just as Mads answered in this question: https://stackoverflow.com/a/59328672/2672518. In that answer, the result is that you get a warning on the return. In this case, the answer is that you get a warning that you dereferenced a possibly null reference.
It does not become nullable, simply because we were silly enough to compare it with null.
Yep, it actually does. To the compiler. As humans, we can look at this code and obviously understand that it cannot throw a null reference exception. But the way the nullable flow analysis is implemented in the compiler, it cannot. We did discuss some amount of improvements to this analysis where we add additional states based on where the value came from, but we decided that this added a great deal of complexity to the implementation for not a great deal of gain, because the only places where this would be useful is for cases like this, where the user initializes a variable with a new or a constant value and then checks it for null anyway.
If nullability inference is not bullet-proof, [..] how can it go wrong?
I happily adopted the nullable references of C#8 as soon as they were available. As I was used to use the [NotNull] (etc.) notation of ReSharper, I did notice some differences between the two.
The C# compiler can be fooled, but it tends to err on the side of caution (usually, not always).
As a reference for future visitors, these are the scenarios I saw the compiler being pretty confused about (I assume all these cases are by design):
Null forgiving null. Often used to avoid the dereference warning, but keeping the object non-nullable. It looks like wanting to keep your foot in two shoes.
string s = null!; //No warning
Surface analysis. In opposition to ReSharper (that does it using code annotation), the C# compiler does still not support a full range of attributes to handle the nullable references.
void DoSomethingWith(string? s)
{
ThrowIfNull(s);
var split = s.Split(' '); //Dereference warning
}
It does, though, allow to use some construct to check for nullability that also get rid of the warning:
public static void DoSomethingWith(string? s)
{
Debug.Assert(s != null, nameof(s) + " != null");
var split = s.Split(' '); //No warning
}
or (still pretty cool) attributes (find them all here):
public static bool IsNullOrEmpty([NotNullWhen(false)] string? value)
{
...
}
Susceptible code analysis. This is what you brought to light. The compiler has to make assumptions in order to work and sometimes they might seem counter-intuitive (for humans, at least).
void DoSomethingWith(string s)
{
var b = s == null;
var i = s.Length; // Dereference warning
}
Troubles with generics. Asked here and explained very well here (same article as before, paragraph "The issue with T?"). Generics are complicated as they have to make both references and values happy. The main difference is that while string? is just a string, int? becomes a Nullable<int> and forces the compiler to handle them in substantially different ways. Also here, the compiler is choosing the safe path, forcing you to specify what you are expecting:
public interface IResult<out T> : IResult
{
T? Data { get; } //Warning/Error: A nullable type parameter must be known to be a value type or non-nullable reference type.
}
Solved giving constrains:
public interface IResult<out T> : IResult where T : class { T? Data { get; }}
public interface IResult<T> : IResult where T : struct { T? Data { get; }}
But if we do not use constraints and remove the '?' from Data, we are still able to put null values in it using the 'default' keyword:
[Pure]
public static Result<T> Failure(string description, T data = default)
=> new Result<T>(ResultOutcome.Failure, data, description);
// data here is definitely null. No warning though.
The last one seems the trickier to me, as it does allow to write unsafe code.
Hope this helps someone.

Best way to check for null parameters (Guard Clauses)

For example, you usually don't want parameters in a constructor to be null, so it's very normal to see some thing like
if (someArg == null)
{
throw new ArgumentNullException(nameof(someArg));
}
if (otherArg == null)
{
throw new ArgumentNullException(nameof(otherArg));
}
It does clutter the code a bit.
Is there any way to check an argument of a list of arguments better than this?
Something like "check all of the arguments and throw an ArgumentNullException if any of them is null and that provides you with the arguments that were null.
By the way, regarding duplicate question claims, this is not about marking arguments with attributes or something that is built-in, but what some call it Guard Clauses to guarantee that an object receives initialized dependencies.
With newer version of C# language you can write this without additional library or additional method call:
_ = someArg ?? throw new ArgumentNullException(nameof(someArg));
_ = otherArg ?? throw new ArgumentNullException(nameof(otherArg));
Starting from .NET6 you can also write this:
ArgumentNullException.ThrowIfNull(someArg);
Starting from .NET7 you can handle empty string and null checking:
ArgumentException.ThrowIfNullOrEmpty(someStringArg);
public static class Ensure
{
/// <summary>
/// Ensures that the specified argument is not null.
/// </summary>
/// <param name="argumentName">Name of the argument.</param>
/// <param name="argument">The argument.</param>
[DebuggerStepThrough]
[ContractAnnotation("halt <= argument:null")]
public static void ArgumentNotNull(object argument, [InvokerParameterName] string argumentName)
{
if (argument == null)
{
throw new ArgumentNullException(argumentName);
}
}
}
usage:
// C# < 6
public Constructor([NotNull] object foo)
{
Ensure.ArgumentNotNull(foo, "foo");
...
}
// C# >= 6
public Constructor([NotNull] object bar)
{
Ensure.ArgumentNotNull(bar, nameof(bar));
...
}
The DebuggerStepThroughAttribute comes in quite handy so that in case of an exception while debugging (or when I attach the debugger after the exception occurred) I will not end up inside the ArgumentNotNull method but instead at the calling method where the null reference actually happened.
I am using ReSharper Contract Annotations.
The ContractAnnotationAttribute makes sure that I never misspell
the argument ("foo") and also renames it automatically if I rename
the foo symbol.
The NotNullAttribute helps ReSharper with code analysis. So if I do new Constructor(null) I will get a warning from ReSharper that this will lead to an exception.
If you do not like to annotate your code directly,
you can also do the same thing with external XML-files that you could deploy with your library and that users can optionally reference in their ReSharper.
If you have too many parameters in your constructors, you'd better revise them, but that's another story.
To decrease boilerplate validation code many guys write Guard utility classes like this:
public static class Guard
{
public static void ThrowIfNull(object argumentValue, string argumentName)
{
if (argumentValue == null)
{
throw new ArgumentNullException(argumentName);
}
}
// other validation methods
}
(You can add other validation methods that might be necessary to that Guard class).
Thus it only takes one line of code to validate a parameter:
private static void Foo(object obj)
{
Guard.ThrowIfNull(obj, "obj");
}
Null references are one sort of troubles you have to guard against. But, they are not the only one. The problem is wider than that, and it boils down to this: Method accepts instances of a certain type, but it cannot handle all instances.
In other words, domain of the method is larger than the set of values it handles. Guard clauses are then used to assert that actual parameter does not fall into that "gray zone" of the method's domain which cannot be handled.
Now, we have null references, as a value which is typically outside the acceptable set of values. On the other hand, it often happens that some non-null elements of the set are also unacceptable (e.g. empty string).
In that case, it may turn out that the method signature is too broad, which then indicates a design problem. That may lead to a redesign, e.g. defining a subtype, typically a derived interface, which restricts domain of the method and makes some of the guard clauses disappear. You can find an example in this article: Why do We Need Guard Clauses?
With newer version of C# (C# 10, .NET6 will be released in a few days) you can even do:
ArgumentNullException.ThrowIfNull(someArg);
Doc: https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception.throwifnull?view=net-6.0
Ardalis has an excellent GuardClauses library.
It's nice to use Guard.Against.Null(message, nameof(message));
In C# 8.0 and later, new helps are available. C# 8.0 introduces non-nullable reference types (a feature somewhat confusingly called "nullable reference types" in the docs). Prior to C# 8.0, all reference types could be set to null. But now with C# 8.0 and the 'nullable' project setting, we can say that reference types are by default non-nullable, and then make our variables and parameters nullable on a case-by-case basis.
So whereas at the moment, we recognize code like this:
public void MyFunction(int thisCannotBeNull, int? thisCouldBeNull)
{
// no need for checking my thisCannotBeNull parameter for null here
}
If you set <Nullable>enable</Nullable> for your C# v8.0+ project, you can do things like this too:
public void MyFunction(MyClass thisCannotBeNull, MyClass? thisCouldBeNull)
{
// static code analysis at compile time checks to see if thisCannotBeNull could be null
}
The null-checking is done at compile-time, using static code analysis. So if you've coded it in a way that means a null could turn up there, you'll get a compiler warning (which you can upgrade to an error if you want). So lots (but not all) of the situations where you need a run-time check for null parameters can be handled as a compile-time check based on your code.
The !! operator (not actually part of C#, but interesting story)
Microsoft attempted to introduce a new language feature that was known as parameter null checking or also as the bang bang operator in C# 10 and later again in C# 11, but decided to not release it.
It would have been the shortest way to do this (by far): only 2 exclamation marks !! right after the argument(s) you want to check for null.
Before:
public void test(string someArg){
if (someArg == null)
{
throw new ArgumentNullException(nameof(someArg));
}
// other code
}
With that new operator:
public void test(string someArg!!){
// other code
}
Calling test(null) would have lead to an ArgumentNullException telling you that someArg is null.
Microsoft mentioned it in early 2021, but it did not become part of C# 10: A video on the 'Microsoft Developer' YouTube channel explaining the new feature.
The feature was implemented in February 2022 for C#11, see on GitHub.
It was removed later see on Microsoft dev blog because of lots of criticism with the argument, that the bang bang operator is very shouty.
The developers of the C# language think, that there is a majority for such a feature, but that it's not as large as usual and that it's possible, that this features comes with a later C# version.
You might try my Heleonix.Guard library, which provides guard functionality.
You can write guard clauses like below:
// C# 7.2+: Non-Trailing named arguments
Throw.ArgumentNullException(when: param.IsNull(), nameof(param));
// OR
// Prior to C# 7.2: You can use a helper method 'When'
Throw.ArgumentNullException(When(param.IsNull()), nameof(param));
// OR
Throw.ArgumentNullException(param == null, nameof(param));
// OR
Throw.ArgumentNullException(When (param == null), nameof(param));
It provides throwing of many existing exceptions, and you can write custom extension methods for custom exceptions. Also, the library refers to the 'Heleonix.Extensions' library with predicative extensions like IsNull, IsNullOrEmptyOrWhitespace, IsLessThan and many more to check your arguments or variables against desired values. Unlike some other guard libraries with fluent interfaces, these extensions do not generate intermediate objects, and since implementation is really straightforward, they are performant.
If you want to save typing the argument name twice, like
Guard.AgainstNull(arg, nameof(arg));
check out YAGuard, where you can write
Guard.AgainstNull(arg);
No need to specify the name of the argument in the guard clause, but in the argument thrown, the name is correctly resolved.
It also supports guard-and-set in the form
MyProperty = Assign.IfNotNull(arg);
Nuget: YAGuard
Disclaimer: I'm the author of YAGuard.
The simplest approach I've found is inspired by Dapper's use of anonymous types.
I've written a Guard class that uses anonymous types to get name of properties.
The guard itself is the following
public class Guard
{
public static void ThrowIfNull(object param)
{
var props = param.GetType().GetProperties();
foreach (var prop in props)
{
var name = prop.Name;
var val = prop.GetValue(param, null);
_ = val ?? throw new ArgumentNullException(name);
}
}
}
You then use it like so
...
public void Method(string someValue, string otherValue)
{
Guard.ThrowIfNull(new { someValue, otherValue });
}
...
When the ArgumentNullException is thrown, reflection is used to determine the name of the property which will then be displayed in your exception
There is a nuget package called SwissKnife. Install SwissKnife from nuget gallery. It provides you with many options starting with null checking for arguments
Argument.IsNotNullOrEmpty(args,"args") under SwissKnife.Diagnostics.Contracts namespace alongwith with option idoim and many more. You can set Option<Class_Name> _someVar and then check if _someVar.IsSome or _someVar.IsNone. This helps against nullable classes as well. Hope this helps.

Syntax alternatives to casting of dynamic objects

I have an implementation of DynamicDictionary where all of the entries in the dictionary are of a known type:
public class FooClass
{
public void SomeMethod()
{
}
}
dynamic dictionary = new DynamicDictionary<FooClass>();
dictionary.foo = new FooClass();
dictionary.foo2 = new FooClass();
dictionary.foo3 = DateTime.Now; <--throws exception since DateTime is not FooClass
What I'd like is to be able to have Visual Studio Intellisense work when referencing a method of one of the dictionary entries:
dictionary.foo.SomeMethod() <--would like SomeMethod to pop up in intellisense
The only way I've found to do this is:
((FooClass)dictionary.foo).SomeMethod()
Can anyone recommend a more elegant syntax? I'm comfortable writing a custom implementation of DynamicDictionary with IDynamicMetaObjectProvider.
UPDATE:
Some have asked why dynamics and what my specific problem is. I have a system that lets me do something like this:
UI.Map<Foo>().Action<int, object>(x => x.SomeMethodWithParameters).Validate((parameters) =>
{
//do some method validation on the parameters
return true; //return true for now
}).WithMessage("The parameters are not valid");
In this case the method SomeMethodWithParameters has the signature
public void SomeMethodWithParameters(int index, object target)
{
}
What I have right now for registering validation for individual parameters looks like this:
UI.Map<Foo>().Action<int, object>(x => x.SomeMethodWithParameters).GetParameter("index").Validate((val) =>
{
return true; //valid
}).WithMessage("index is not valid");
What I'd like it to be is:
UI.Map<Foo>().Action<int, object(x => x.SomeMethodWithParameters).index.Validate((val) =>
{
return true;
}).WithMessage("index is not valid");
This works using dynamics, but you lose intellisense after the reference to index - which is fine for now. The question is is there a clever syntactical way (other than the ones metioned above) to get Visual Studio to recognize the type somehow. Sounds so far like the answer is "no".
It seems to me that if there was a generic version of IDynamicMetaObjectProvider,
IDynamicMetaObjectProvider<T>
this could be made to work. But there isn't, hence the question.
In order to get intellisense, you're going to have to cast something to a value that is not dynamic at some point. If you find yourself doing this a lot, you can use helper methods to ease the pain somewhat:
GetFoo(dictionary.Foo).SomeMethod();
But that isn't much of an improvement over what you've got already. The only other way to get intellisense would be to cast the value back to a non-dynamic type or avoid dynamic in the first place.
If you want to use Intellisense, it's usually best to avoid using dynamic in the first place.
typedDictionary["foo"].SomeMethod();
Your example makes it seem likely that you have specific expectations about the structure of your dynamic object. Consider whether there's a way to create a static class structure that would fulfill your needs.
Update
In response to your update: If you don't want to drastically change your syntax, I'd suggest using an indexer so that your syntax can look like this:
UI.Map<Foo>().Action<int, object>(x => x.SomeMethodWithParameters)["index"].Validate((val) => {...});
Here's my reasoning:
You only add four characters (and subtract one) compared to the dynamic approach.
Let's face it: you are using a "magic string." By requiring an actual string, this fact will be immediately obvious to programmers who look at this code. Using the dynamic approach, there's nothing to indicate that "index" is not a known value from the compiler's perspective.
If you're willing to change things around quite a bit, you may want to investigate the way Moq plays with expressions in their syntax, particularly the It.IsAny<T>() method. It seems like you might be able to do something more along these lines:
UI.Map<Foo>().Action(
(x, v) => x.SomeMethodWithParameters(
v.Validate<int>(index => {return index > 1;})
.WithMessage("index is not valid"),
v.AlwaysValid<object>()));
Unlike your current solution:
This wouldn't break if you ended up changing the names of the parameters in the method signature: Just like the compiler, the framework would pay more attention to the location and types of the parameters than to their names.
Any changes to the method signature would cause an immediate flag from the compiler, rather than a runtime exception when the code runs.
Another syntax that's probably slightly easier to accomplish (since it wouldn't require parsing expression trees) might be:
UI.Map<Foo>().Action((x, v) => x.SomeMethodWithParameters)
.Validate(v => new{
index = v.ByMethod<int>(i => {return i > 1;}),
target = v.IsNotNull()});
This doesn't give you the advantages listed above, but it still gives you type safety (and therefore intellisense). Pick your poison.
Aside from Explict Cast,
((FooClass)dictionary.foo).SomeMethod();
or Safe Cast,
(dictionary.foo as FooClass).SomeMethod();
the only other way to switch back to static invocation (which will allow intellisense to work) is to do Implicit Cast:
FooClass foo = dictionary.foo;
foo.SomeMethod().
Declared casting is your only option, can't use helper methods because they will be dynamically invoked giving you the same problem.
Update:
Not sure if this is more elegant but doesn't involve casting a bunch and gets intellisense outside of the lambda:
public class DynamicDictionary<T>:IDynamicMetaObjectProvider{
...
public T Get(Func<dynamic,dynamic> arg){
return arg(this);
}
public void Set(Action<dynamic> arg){
arg(this);
}
}
...
var dictionary = new DynamicDictionary<FooClass>();
dictionary.Set(d=>d.Foo = new FooClass());
dictionary.Get(d=>d.Foo).SomeMethod();
As has already been said (in the question and StriplingWarrior answer) the C# 4 dynamic type does not provide intellisense support. This answer is provided merely to provide an explanation why (based on my understanding).
dynamic to the C# compiler is nothing more than object which has only limited knowledge at compile-time which members it supports. The difference is, at run-time, dynamic attempts to resolve members called against its instances against the type for which the instance it represents knows (providing a form of late binding).
Consider the following:
dynamic v = 0;
v += 1;
Console.WriteLine("First: {0}", v);
// ---
v = "Hello";
v += " World";
Console.WriteLine("Second: {0}", v);
In this snippet, v represents both an instance of Int32 (as seen in the first section of code) and an instance of String in the latter. The use of the += operator actually differs between the two different calls to it because the types involved are inferred at run-time (meaning the compiler doesn't understand or infer usage of the types at compile-time).
Now consider a slight variation:
dynamic v;
if (DateTime.Now.Second % 2 == 0)
v = 0;
else
v = "Hello";
v += 1;
Console.WriteLine("{0}", v);
In this example, v could potentially be either an Int32 or a String depending on the time at which the code is run. An extreme example, I know, though it clearly illustrates the problem.
Considering a single dynamic variable could potentially represent any number of types at run-time, it would be nearly impossible for the compiler or IDE to make assumptions about the types it represents prior to it's execution, so Design- or Compile-time resolution of a dynamic variable's potential members is unreasonable (if not impossible).

Is there a way to mark a method as ensuring that T is not null?

For example, if I have a method defined as...
T Create()
{
T t = Factory.Create<T>();
// ...
Assert.IsNotNull(t, "Some message.");
// -or-
if (t == null) throw new Exception("...");
// -or- anything that verifies that it is not null
}
...and I am calling that method from somewhere else...
void SomewhereElse()
{
T t = Create();
// >><<
}
...at >><<, I know (meaning me, the person who wrote this) that t is guaranteed to not be null. Is there a way (an attribute, perhaps, that I have not found) to mark a method as ensuring that a reference type that it returns or otherwise passes out (perhaps an out parameter) is guaranteed by internal logic to not be null?
I have to sheepishly admit that ReSharper is mostly why I care as it highlights anything it thinks could cause either InvalidOperationException or NullReferenceException. I figure either it's reading something that I can mark on my methods or it just knows that Assert.IsNotNull, simple boolean checks or a few other things will remove the chance of something being null and that it can remove the highlight.
Any thoughts? Am I just falling victim to oh-my-god-resharper-highlights-it-I-have-to-fix-it disease?
If ReSharper is why you care then you can mark the Factory.Create<T>() method with their [NotNull] attribute described in their web help
Not sure how R# handles this, but the Contract.Assert method may be what you're looking for
You could put a constraint on T to only allow struct.
You could use a language extension that allows you to make stronger definitions of pre/post conditions for your function (contract based programming), like SpecSharp, or Code Contracts. Code Contracts seems to leverage built-in systems from C# 4.0. I have no experience with either - only heard of them.
Could you cast T to an object then check if its null?
var o = (object)Factory.Create<T>();
if(o == null) throw new Exception();

How does ReSharper know "Expression is always true"?

Check out the following code:
private void Foo(object bar)
{
Type type = bar.GetType();
if (type != null) // Expression is always true
{
}
}
ReSharper claims type will never be null. That's obvious to me because there's always going to be a type for bar, but how does ReSharper know that? How can it know that the result of a method will never be null?
Type is not a struct so it can't be that. And if the method were written by me, then the return value could certainly be null (not necessarily GetType, but something else).
Is ReSharper clever enough to know that, for only that particular method, the result will never be null? (Like there's a hard-coded list of known .NET methods which will never return null.)
JetBrains perfectly explains how ReSharper does this in their features list.
Summary from link (this particular question is about NotNullAttribute):
We have analyzed a great share of .NET Framework Class Library, as well as NUnit Framework, and annotated it through external XML files, using a set of custom attributes from the JetBrains.Annotations namespace, specifically:
StringFormatMethodAttribute (for methods that take format strings as parameters)
InvokerParameterNameAttribute (for methods with string literal arguments that should match one of caller parameters)
AssertionMethodAttribute (for assertion methods)
AssertionConditionAttribute (for condition parameters of assertion methods)
TerminatesProgramAttribute (for methods that terminate control flow)
CanBeNullAttribute (for values that can be null)
NotNullAttribute (for values that can not be null)
UsedImplicitlyAttribute (for entities that should not be marked as unused)
MeansImplicitUseAttribute (for extending semantics of any other attribute to mean that the corresponding entity should not be marked as unused)
Yes, it basically has knowledge of some well-known methods. You should find the same for string concatenation too, for example:
string x = null;
string y = null;
string z = x + y;
if (z == null)
{
// ReSharper should warn about this never executing
}
Now the same information is also becoming available via Code Contracts - I don't know whether JetBrains is hooking directly into this information, has its own database, or a mixture of the two.
GetType is not virtual. Your assumption is most likely correct in your last statement.
Edit: to answer your comment question - it can't infer with your methods out of the box.
object.GetType is not virtual, so you cannot yourself implement a version that returns a null value. Therefore, if bar is null, you will get a NullReferenceException and otherwise, type will never by null.

Categories

Resources