I've always thought that it's impossible for this to be null inside instance method body. Following simple program demonstrates that it is possible. Is this some documented behaviour?
class Foo
{
public void Bar()
{
Debug.Assert(this == null);
}
}
public static void Test()
{
var action = (Action)Delegate.CreateDelegate(typeof (Action), null, typeof(Foo).GetMethod("Bar"));
action();
}
UPDATE
I agree with the answers saying that it's how this method is documented. However, I don't really understand this behaviour. Especially because it's not how C# is designed.
We had gotten a report from somebody (likely one of the .NET groups
using C# (thought it wasn't yet named C# at that time)) who had
written code that called a method on a null pointer, but they didn’t
get an exception because the method didn’t access any fields (ie
“this” was null, but nothing in the method used it). That method then
called another method which did use the this point and threw an
exception, and a bit of head-scratching ensued. After they figured it
out, they sent us a note about it.
We thought that being able to call a method on a null instance was a
bit weird. Peter Golde did some testing to see what the perf impact
was of always using callvirt, and it was small enough that we decided
to make the change.
http://blogs.msdn.com/b/ericgu/archive/2008/07/02/why-does-c-always-use-callvirt.aspx
Because you're passing null into the firstArgument of Delegate.CreateDelegate
So you're calling an instance method on a null object.
http://msdn.microsoft.com/en-us/library/74x8f551.aspx
If firstArgument is a null reference and method is an instance method,
the result depends on the signatures of the delegate type type and of
method:
If the signature of type explicitly includes the hidden first
parameter of method, the delegate is said to represent an open
instance method. When the delegate is invoked, the first argument in
the argument list is passed to the hidden instance parameter of
method.
If the signatures of method and type match (that is, all parameter
types are compatible), then the delegate is said to be closed over a
null reference. Invoking the delegate is like calling an instance
method on a null instance, which is not a particularly useful thing to
do.
Sure you can call into a method if you are using the call IL instruction or the delegate approach. You will set this booby trap only off if you try to access member fields which will give you the NullReferenceException you did seek for.
try
int x;
public void Bar()
{
x = 1; // NullRefException
Debug.Assert(this == null);
}
The BCL does even contain explicit this == null checks to aid debugging for languages which do not use callvirt (like C#) all the time. See this question for further infos.
The String class for example has such checks. There is nothing mysterious about them except that you will not see the need for them in languages like C#.
// Determines whether two strings match.
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public override bool Equals(Object obj)
{
//this is necessary to guard against reverse-pinvokes and
//other callers who do not use the callvirt instruction
if (this == null)
throw new NullReferenceException();
String str = obj as String;
if (str == null)
return false;
if (Object.ReferenceEquals(this, obj))
return true;
return EqualsHelper(this, str);
}
Try the documentation for Delegate.CreateDelegate() at msdn.
You're "manually" calling everything, and thus instead of passing an instance in for the this pointer, you're passing null. So it can happen, but you have to try really really hard.
this is a reference, so there is no problem with its being null from the perspective of the type system.
You may ask why NullReferenceException was not thrown. The full list of circumstances when CLR throws that exception is documented. Your case is not listed. Yes, it is a callvirt, but to Delegate.Invoke (see here) rather than to Bar, and so the this reference is actually your non-null delegate!
The behavior you see has an interesting implementational consequence for CLR. A delegate has a Target property (corresponds to your this reference) that is quite frequently null, namely when the delegate is static (imagine Bar be static). Now there is, naturally, a private backing field for the property, called _target. Does _target contain a null for a static delegate? No it doesn't. It contains a reference to the delegate itself. Why not null? Because a null is a legitimate target of a delegate as your example shows and CLR does not have two flavors of a null pointer to distinguish the static delegate somehow.
This bit of trivium demonstrates that with delegates, null targets of instance methods are no afterthought. You may still be asking the ultimate question: but why they had to be supported?
The early CLR had an ambitious plan of becoming, among others, the platform of choice even for sworn C++ developers, a goal that was approached first with Managed C++ and then with C++/CLI. Some too challenging language features were omitten, but there was nothing really challenging about supporting instance methods executing without an instance, which is perfectly normal in C++. Including delegate support.
The ultimate answer therefore is: because C# and CLR are two different worlds.
More good reading and even better reading to show the design allowing null instances shows its traces even in very natural C# syntactic contexts.
this is a readonly reference in C# classes. Accordingly and as expected this can be used like any other references (in read only mode) ...
this == null // readonly - possible
this = new this() // write - not possible
Related
Below are the MSDN reference links for the Out keyword and the Ref keyword.
Out Keyword
Ref Keyword
Both Ref and Out keywords are pass by reference, then why it is required for one to be initialized and the other needn't to be initialized? Is it something by design convention or is there any other reason/meaning behind the same? Need some help.
A reference is basically the Address part of:
[Address] => points to => [Object]
The ref keyword passes the address of an existing object. The method can use the object at that address or instantiate an entirely new one (but at the same address). The address does need to be initialized, even if the value it holds is null. (Below is a little test driver that show this).
The out keyword says that the method must instantiate (or set to null) an object (not an address) that it returns.
[TestMethod]
public void TestMethod2()
{
MyClass myClass;
myClass = new MyClass(1);
// Initializing the ADDRESS as an existing object.
ByRefDemo(ref myClass);
Console.WriteLine($"Returned value is: {myClass}");
// Initializing the ADDRESS as a null object.
myClass = null;
ByRefDemo(ref myClass);
Console.WriteLine($"Returned value is: {myClass}");
}
class MyClass
{
public MyClass(int value)
{
Value = value;
}
public int Value { get; }
public override string ToString() => $"{Value}";
}
void ByRefDemo(ref MyClass addressOf)
{
var value = addressOf == null ? "NULL" : $"{addressOf}";
Console.WriteLine($"Incoming value is: {value}" );
addressOf = new MyClass(2);
}
You may be looking at this from the wrong perspective.
ref and out are both modifiers that are used in a function signature declaration, but they aren't really similar otherwise. They shouldn't both do the same thing or have the same requirements.
ref tells the compiler that you want a reference to something that would ordinarily be passed by value. You are passing a live object. Therefore, you have to already have a live object that you want to pass.
out tells the compiler that you want an output variable. It acts precisely as another function return value. Just like the function return value, anything assigned to it before the function is called will be overwritten by the value set in the function. So your output variable may be declared and even initialized or set but its value will be overwritten anyway.
You may use ref to do something similar to out, which may be dangerous and may violate best practices or other standards that you're using (it does commonly). Using out instead of ref won't work though.
There will be occasions when you're programming, that you aren't programming for yourself; you're programming for the benefit of someone else. Imagine you're writing some awesome parsing library or something..
There aren't any surprises for someone calling your method if they're passing you some reference type by value semantics; C# makes sure your method gets a copy of their reference. You can modify the contents of the instance at end of the reference, sure, but you can't surprise the caller by swapping out the reference they gave you for something else
It's different with things passed by original reference; they could give you some carefully crafted object that took hours to make and you could trash it by setting the reference to null. It would be nice for them to know this ahead of time, so they could keep their own copy of the reference
As such, with your arguments that are passed by original reference rather than by copy, you have 3 choices with which to decorate them to help indicate your intentions towards their data:
out - "don't bother spending hours crafting the perfect object; I will overwrite the reference you give"
ref - "give me some data, but don't be surprised if I replace your object with another. Keep your own reference if you're precious about losing it"
in - "the pass will be done by original reference but I promise I won't swap it out for something else"
The compiler helps you make the first and last promise by insisting that you do set an out/don't set an in; and this is essentially the answer to your question: in/out/ref behave the way they do by design to help you make the promises you make when you use one of them on an argument
out and ref perhaps don't seem to have much of a point if you're looking at things from "I'm going to write this method here and use it there" but it does help describe to someone else (who cannot see the inner workings of what your method does) what you will do with their thing they provide, and that's quite important but easy to overlook if you you don't have that "external caller" perspective in mind
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.
Quick question.
In the second example on this documentation page (the second code block, featuring a method called CompareDinosByLength), the Sort method is called as such:
dinosaurs.Sort(CompareDinosByLength);
Why is it that the Sort method didn't need an explicitly declared delegate, as I would have thought by reading the Delegate documentation? Before I found that example, I was attempting to do it like so:
delegate int CompareDinosDel(string first, string second);
CompareDinosDel newDel = CompareDinosByLength;
dinosaurs.Sort(newDel);
But I kept getting errors related to the delegate / delegate method not being proper Comparers.
Shouldn't both work?
Why is it that the Sort method didn't need an explicitly declared delegate?
C# permits a method group -- that is, a method which is named without having the (...) argument list to invoke it -- to be used in a context where a delegate is expected. The compiler performs overload resolution on the method group as though the method group had been invoked with arguments of the types of the delegate's formal parameters. This determines which method of the method group should be used to create the delegate.
This overload resolution process can sometimes lead to unusual situations involving method type inference when the method group is undergoing overload resolution to a delegate type which is a formal parameter type of a generic method; Sort, fortunately is not a generic method, so these oddities do not come into play.
This feature was added to C# 2.0; before that a method group had to be converted to a delegate via
new MyDelegate(MyMethod)
I keep getting errors related to the delegate / delegate method not being proper Comparers. Shouldn't both work?
Unfortunately, no. C# does not have structural identity on delegate types. That is:
delegate void Foo();
delegate void Bar();
...
Foo foo = ()=>{};
Bar bar = foo; // ERROR!
Even though Foo and Bar are structurally identical, the compiler disallows the conversion. You can however use the previous trick:
Bar bar = foo.Invoke;
This is equivalent to
Bar bar = new Bar(foo.Invoke);
However the new bar has as its action to invoke foo; it goes through a level of indirection.
This feature does make some sense.
Reason one:
You don't expect structural identity to work in other places:
struct Point { int x; int y; ... }
struct Pair { int key; int value; ... }
....
Point point = whatever;
Pair pair = point; // ERROR
Reason two:
You might want to say:
delegate int PureMethod(int);
And have a convention that PureMethod delegates are "pure" -- that is, the methods they represent do not throw, always return, return a value computed only from their argument, and produce no side effects. It should be an error to say
Func<int, int> f = x => { Console.WriteLine(x); return x+1; };
PureMethod p = f;
Because f is not pure.
However in hindsight people do not actually make semantics-laden delegates. It is a pain point that a value of type Predicate<int> cannot be assigned to a variable of type Func<int, bool> and vice versa.
If we had to do it all over again, I suspect that delegates would have structural identity in the CLR.
Finally, I note that VB is much more forgiving about inter-assigning mixed delegate types; it automatically builds an adapter delegate if it needs to. This can be confusing because sometimes it looks like referential identity is maintained when in fact it is not, but this is in keeping with the VB philosophy of "just make my code work".
dinosaurs.Sort(CompareDinosByLength);
CompareDinosDel newDel = CompareDinosByLength;
dinosaurs.Sort(newDel);
Shouldn't both work?
No, because you are passing two very different things into those two function calls.
The key here is to recognize that, in both cases, what you actually pass into the method is a delegate. In the first case, the compiler is implicitly creating a delegate of the correct type for you, even though you didn't explicitly ask it to. In the second case, you're making your own delegate, but it's the wrong type, so that attempt will fail.
Starting with .NET 2.0, the C# compiler allow you to skip explicitly create delegates in many situations. If you use a method name in a context where a delegate is expected, and the compiler can verify that the method signature and delegate signature match, it will implicitly construct a delegate instance using the method. That is, instead of doing this (the "old" way)
this.SubmitButton.Click += new System.EventHandler(this.SubmitButton_Click);
You can now do this:
this.SubmitButton.Click += this.SubmitButton_Click;
Visual Studio itself will still generate the older syntax, I assume because it still works and because it's not worth the developer's time to go messing around with it for very little benefit. However, most popular code analysis tools will flag the redundant delegate creation if you use it in your own code.
This same technique works anywhere you have a method (technically a "method group", since one method name can refer to more than one overload), and you assign it to a variable of a delegate type. Passing a method as a parameter into another method is the same type of assignment operation: you are "assigning" the actual parameter at the call site to the formal parameter in the method body, so the compiler does the same thing. In other words, the following two method calls do exactly the same thing:
dinosaurs.Sort(CompareDinosByLength);
dinosaurs.Sort(new Comparison<string>(CompareDinosByLength));
Your unsuccessful attempt to make a delegate, on the other hand, did something slightly different:
dinosaurs.Sort(new CompareDinosDel(CompareDinosByLength));
This time, you told the compiler exactly what kind of delegate you wanted, but that's not the kind of delegate that the method expected. In general, the compiler isn't going to try to second guess what you told it do to; if you ask it to do something that looks "fishy", it will produce an error (in this case, a type mismatch error).
This behavior is similar to what would happen if you tried to do this:
public class A
{
public int x;
}
public class B
{
public int x;
}
public void Foo(A a) { }
public void Bar()
{
B b = new B();
this.Foo(b);
}
In this case, A and B are two distinct types, even though their "type signature" is exactly the same. Any line of code that works on an A will also work equally well on a B, but yet, we cannot use them interchangeably. Delegates are types like any other types, and C#'s type safety rules require that we use the correct delegate types where we need them, and can't get away with just using a close enough type.
The reason this is a good thing is because a delegate type may have a lot more meaning that just it's technical components would imply. Like any other data type, when we create delegates for our applications, we usually apply some kind of semantic meaning to those types. We expect, for example, that if we have a ThreadStart delegate, that it's going to be associated with a method that runs when a new thread starts. the delegate's signature is about as simple as you get (no parameters, no return value) but the implication behind the delegate is very important.
Because of that, we generally want the compiler to tell us if we try to use the wrong delegate type in the wrong place. More often than not, that's probably a sign that we are about to do something that may compile, and even run, but is likely to do the wrong thing. That's never something you want from your program.
While all that is true, it's also true that often times you really don't want to assign any semantic meaning to your delegates, or else, the meaning is assigned by some other part of your application. Sometimes you really do just want to pass around an arbitrary piece of code that has to run later. This is very common with functional-style programs or asynchronous programs, where you get things like continuations, callbacks, or user-supplied predicates (look at the various LINQ methods, for example). .NET 3.5 and onward supply a very useful set of completely generic delegates, in the Action and Func family, for this purpose.
Consider the following code:
public class Foo
{
public int Bar { get; set; }
}
public class SomeOtherFoo
{
public int Bar { get; set; }
}
Should I be able to say:
Foo foo = new SomeOtherFoo();
That won't work in C# either. When you have two different types that have the same body/implementation, they are still different types. Two classes with the same properties are still different classes. Two different delegates with the same signature are still different delegates.
The Sort method has already defined the delegate type, and you need to match it. This is very much like it defining a class that it needs to accept as a parameter; you can't just pass in another type with the same properties and methods.
This is what it means for a language to be statically typed. An alternate type system would be to use "Duck Typing" in which the language doesn't apply the constraint that a variable be of a specific type, but rather that it has a specific set of members. In other words, "If it walks like a duck, and quacks like a duck, pretend it's a duck." That is opposed to the style of typing that says, "It must be a duck, period, even if it knows how to walk and quack."
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();
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.