The following extension method tries, for a given value of unknown type, to find a constructor with a single parameter such that the constructor can be called with that value.
private static ConstructorInfo ConstructorThatTakesValue
(this Type thisType, object value)
{
return thisType.GetConstructors().FirstOrDefault(c =>
c.GetParameters().Count() == 1 &&
c.GetParameters().First().ParameterType.IsAssignableFrom(value.GetType()));
}
That is, if var c = typeof(X).ConstructorThatTakesValue(y), then we can create a x by
var x = (X)c.Invoke(new object[] { y });
The code above works like a charm, but Resharper marks the line containing IsAssignableFrom and displays "Use method InstanceOfType". It also provides a QuickFix which literally just replaces IsAssignableFrom by IsInstanceOfType, which by my intuition is the exact opposite of what I am trying to achieve:
c.GetParameters().First().ParameterType.IsInstanceOfType(value.GetType()));
Even more suspicious, this message is displayed as a "suggestion", not a warning or so. That is, Resharper seems to consider the change a simple stylistic improvement.
I also tried to gain understanding of the semantics of the two methods, but I was not able to grasp the meaning of documentation on the MSDN either. My understanding would be that if class A : B, then B.GetType().IsAssignableFrom(A.GetType()) and A.GetType().IsInstanceOfType(B.GetType()).
One works with Types and the Other instances, in fact one calls the other:
public virtual bool IsInstanceOfType(object o)
{
if (o == null)
{
return false;
}
return this.IsAssignableFrom(o.GetType());
}
Kevin Cooks answer is good, but there is an overlook in Resharper's engine: it does not differenciate from Objects and Types (it treat the Type instance as an Object).
As in, if your B argument is already a Type object, it will still ask you to switch to "IsInstanceOf". Which is false and will lead to errors in this very limited context.
EDIT: I double check my test case I founf out it's not longer the case. When the second argument type is indeed Type, it correctly uses the IsAssignableFrom method without warnings.
Related
Just a quick question about method overloading using the new C# 7.0 tuple syntax.
I have created two functions overloads. Simplified, they're along the lines of:
public Boolean TheFunction( string p_in_value )
{
...
return true;
}
and
public ( Boolean Result, long SomeID ) TheFunction( string p_in_value )
{
...
return ( true, _found_id );
}
Now, I would argue that since their respective calls would take the form(s)
_my_bool = TheFunction( "" );
and
( _my_bool, _my_long ) = TheFunction( "" );
that the compiler ought to be able to distinguish between the two, thus fulfilling the basic requirement that when creating overloads, one needs to be able to determine which version you want to call.
Now, I read in another question that as recently as C# 3.0 that the signature of a method does not include its return type, but surely that must no longer apply as I have functions elsewhere that have no problems:
public long ReadHive(string p_section, string p_setting, long p_default) {...}
public bool ReadHive(string p_section, string p_setting, bool p_default) {...}
Nonetheless, I'm getting the syntax error "'Program' already defines a member called 'TheFunction' with the same parameter types".
So unless I'm just looking at the wrong thing, it appears that with this new tuple return syntax, the return types play no part in distinguishing one version from another, which does rather look somewhat short-sighted.
So, my question - am I looking at the wrong thing and this should be possible, or am I out of luck and the new syntax just comes up short in this respect? Or am I even more wrong and am missing some fundamental difference between how my "TheFunction" methods are handled vs. how my "ReadHive" methods are handled?
C# never allowed methods to be different by only their return type. So what you are proposing is not going to compile in the first place.
There is only one exception to this, when implementing implicit conversions:
class Foo
{
public static implicit operator int(Foo f)
{
return 1;
}
public static implicit operator bool(Foo f)
{
return true;
}
}
Compiler creates op_implicit methods that only differ by their return type, like this:
But that's not useful in your situation.
In the example you add:
public long ReadHive(string p_section, string p_setting, long p_default) {...}
public bool ReadHive(string p_section, string p_setting, bool p_default) {...}
the functions are different by the params - third param is long vs. bool.
you cannot distinguish functions only by return type :(
In my haste, I did indeed miss the fundamental difference between the parameter lists. Sorry to have wasted your time. Thank you all for your help - you are the best! Too bad one can't include return type(s) as part of the identifying information, even though "https://learn.microsoft.com/en-us/dotnet/csharp/methods" does state "The return value, or void if the method has none." is part of the signature. Perhaps that just doesn't mean what I thought it meant. Again - thank you all, and sorry for just missing the obvious. Perhaps after I've passed my second month C# programming I'll be better...
I have a test like this:
receivingType.IsAssignableFrom(exportingType))
Which works most of the time, but does not return the desired result when the types involved are delegate types. For example, if exportingType is Action<object, EventArgs> and receivingType is EventHandler, I want the result to be true but the above expression is false. The result I am looking for is true since the two delegates have equivalent method signatures and in fact in C# are actually assignable to each other (although I understand that's probably C# syntax magic).
So my question is, what would the equivalent test look like for delegates that would provide the desired compatibility result?
If you choose to ignore parameter/return type covariance/contravariance (both the variance supported by the compiler since C# 2.0 and the generic covariant/contravariance with in / out), demanding just equality of types, you could use:
public static bool AreCompatible(Type delegate1, Type delegate2)
{
MethodInfo method1 = delegate1.GetMethod("Invoke");
MethodInfo method2 = delegate1.GetMethod("Invoke");
return method1.ReturnType == method2.ReturnType &&
method1.GetParameters().Select(p => p.ParameterType)
.SequenceEqual(method2.GetParameters()
.Select(p => p.ParameterType));
}
(As noted in comments, you might also want to check for out/ref parameters...)
It turned out the below worked very well for me. While I haven't verified that it handles the generic type arg covariance and all that complexity, I suspect it does, and I didn't have to do any of it. :)
internal static bool IsAssignableFrom(Type importingDelegate, Type exportingDelegate)
{
Type importingDelegate, exportingDelegate; // assigned elsewhere
MethodInfo exportingDelegateMethod = exportingDelegate.GetMethod("Invoke");
try
{
exportingDelegateMethod.CreateDelegate(importingDelegate, null);
return true;
}
catch (ArgumentException)
{
return false;
}
}
Since I'm in a portable library, Type.GetMethod doesn't exist, and Type.GetRuntimeMethod doesn't seem to fit. So the above only works outside of a portable library.
For the portable library, I happened to already have the MethodInfo of the exporting method, so I could skip the GetMethod call and go straight to the CreateDelegate test.
Question
I'd like to have a class that is able to handle a null reference of itself. How can I do this? Extension methods are the only way I can think to do this but thought I'd ask in case there was some nifty thing I didn't know about C#.
Example
I have a class called User with a property called IsAuthorized.
When User is properly instantiated IsAuthorized has an implementation. However, when my User reference contains null I'd like a call to IsAuthorized to return false instead of exploding.
Solution
Lot's of good answers. I ended up using three of them to solve my problem.
I used the Null Object design pattern suggested by Zaid Masud.
I combined that with Belmiris' suggestion of using struct so I couldn't have a null reference
And got a great explanation for why C# works this way and how I could really solve it from Jon Hanna
Unfortunately I can only pick one of these as my accepted answer so if you are visiting this page you should take the time to up vote all three of these and any of the other excellent answers that were given.
How about a proper Object Oriented solution? This is exactly what the Null Object design pattern is for.
You could extract an IUser interface, have your User object implement this interface, and then create a NullUser object (that also implements IUser) and always returns false on the IsAuthorized property.
Now, modify the consuming code to depend on IUser rather than User. The client code will no longer need a null check.
Code sample below:
public interface IUser
{
// ... other required User method/property signatures
bool IsAuthorized { get; }
}
public class User : IUser
{
// other method/property implementations
public bool IsAuthorized
{
get { // implementation logic here }
}
}
public class NullUser : IUser
{
public bool IsAuthorized
{
get { return false; }
}
}
Now, your code will return an IUser rather than a User and client code will only depend on IUser:
public IUser GetUser()
{
if (condition)
{
return new NullUser(); // never return null anymore, replace with NullUser instead
}
return new User(...);
}
However, when my User reference contains null I'd like IsAuthorized to always return false instead of exploding.
This can only be done if IsAuthorized is a static method, in which case you can check for null. This is why extension methods can do this - they are really just a different syntax for calling a static method.
Calling a method or property, such as IsAuthorized as an instance method requires an instance. Just the act of calling an instance method (including a property getter) on null will trigger the exception. The exception isn't raised by your class, but by the runtime itself when you attempt to use the (null) reference. There is no way around this in C#.
If the variable is null, it means it references no object, therefore is makes no sense (and I think its not technically possible) to handle the null reference inside the class method.
You should guarantee that it is not null, either by checking just before calling "IsAuthorized" or event before.
Edit: Finding an workaround to do that would be a bad thing: it would be confusing for someone to understand the behavior, since it is not the "expected" behavior for the programming language. It could also cause your code to hide some problem (a null value where it should be an object) and create a bug that will be hard to find. That said: it is for sure a bad idea.
The problem isn't with creating such a method at all. It's with calling the method. If you put a test of if(this == null) in your code, that's perfectly valid. I suppose it could be optimised away by the compiler on the basis of it being "impossible" to be hit, but I thankfully it isn't.
However, when you call the method, it'll be done via callvirt, so rather than call the method directly, it will find the version of the method to call for the particular instance just as it would with a virtual method. Since that will fail for null references, your perfectly good self-null-testing method will fail before it is even called.
C# deliberately does this. According to Eric Gunnerson this was because they thought letting you do so would be a bit weird.
I've never understood why letting a .NET language modelled upon C++ do something that is perfectly allowable in both .NET and the C++ compiler produced by the same company,* was considered a bit weird. I've always considered it a bit weird that it wasn't allowed.
You can add something from another language (F# or IL) that calls the class, or use Reflection.Emit to generate a delegate that does so and that'll work fine. For example, the following code will call the version of GetHashCode defined in object (that is, even if GetHashCode was overridden, this doesn't call the override) which is an example of a method that is safe to call on a null instance:
DynamicMethod dynM = new DynamicMethod(string.Empty, typeof(int), new Type[]{typeof(object)}, typeof(object));
ILGenerator ilGen = dynM.GetILGenerator(7);
ilGen.Emit(OpCodes.Ldarg_0);
ilGen.Emit(OpCodes.Call, typeof(object).GetMethod("GetHashCode"));
ilGen.Emit(OpCodes.Ret);
Func<object, int> RootHashCode = (Func<object, int>)dynM.CreateDelegate(typeof(Func<object, int>));
Console.WriteLine(RootHashCode(null));
The one good thing about this, is that you can hold onto RootHashCode so you only need to build it once (say in a static constructor) and then you can use it repeatedly.
This of course is of no value in letting other code call your method through a null reference, for that extension methods like you suggest are your only bet.
It's also worth noting of course, that if you are writing in a language that doesn't have this quirk of C#, that you should offer some alternative means of getting the "default" result for calling on a null reference because C# people can't get it. Much like C# people should avoid case-only differences between public names because some languages can't deal with that.
Edit: A full example of your question's IsAuthorized being called, since votes suggest some people don't believe it can be done (!)
using System;
using System.Reflection.Emit;
using System.Security;
/*We need to either have User allow partially-trusted
callers, or we need to have Program be fully-trusted.
The former is the quicker to do, though the latter is
more likely to be what one would want for real*/
[assembly:AllowPartiallyTrustedCallers]
namespace AllowCallsOnNull
{
public class User
{
public bool IsAuthorized
{
get
{
//Perverse because someone writing in C# should be expected to be friendly to
//C#! This though doesn't apply to someone writing in another language who may
//not know C# has difficulties calling this.
//Still, don't do this:
if(this == null)
{
Console.Error.WriteLine("I don't exist!");
return false;
}
/*Real code to work out if the user is authorised
would go here. We're just going to return true
to demonstrate the point*/
Console.Error.WriteLine("I'm a real boy! I mean, user!");
return true;
}
}
}
class Program
{
public static void Main(string[] args)
{
//Set-up the helper that calls IsAuthorized on a
//User, that may be null.
DynamicMethod dynM = new DynamicMethod(string.Empty, typeof(bool), new Type[]{typeof(User)}, typeof(object));
ILGenerator ilGen = dynM.GetILGenerator(7);
ilGen.Emit(OpCodes.Ldarg_0);
ilGen.Emit(OpCodes.Call, typeof(User).GetProperty("IsAuthorized").GetGetMethod());
ilGen.Emit(OpCodes.Ret);
Func<User, bool> CheckAuthorized = (Func<User, bool>)dynM.CreateDelegate(typeof(Func<User, bool>));
//Now call it, first on null, then on an object
Console.WriteLine(CheckAuthorized(null)); //false
Console.WriteLine(CheckAuthorized(new User()));//true
//Wait for input so the user will actually see this.
Console.ReadKey(true);
}
}
}
Oh, and a real-life practical concern in this. The good thing about C#'s behaviour is that it causes fail-fast on calls on null-references that would fail anyway because they access a field or virtual somewhere in the middle. This means we don't have to worry about whether we're in a null instance when writing calls. If however you want to be bullet-proof in a fully public method (that is, a public method of a public class), then you can't depend on this. If it's vital that step 1 of a method is always followed by step 2, and step 2 would only fail if called on a null instance, then there should be a self-null check. This is rarely going to happen, but it could cause bugs for non-C# users that you'll never be able to reproduce in C# without using the above technique.
*Though, that is specific to their compiler - it's undefined per the C++ standard IIRC.
Can you use a struct instead? Then it should not ever be null.
You can't reference a property if you do not have a valid instance reference. If you want to be able to reference a property even with a null reference and not put the onus of null-checking on the caller, one way is a static method in User:
static bool IsAuthorized(User user)
{
if(user!=null)
{
return user.IsAuthorized;
}
else
{
return false;
}
}
Then, when you want to check your authorization, instead of:
if(thisUser.IsAuthorized)
Do:
if(User.IsAuthorized(thisUser))
The only way this can work is if you use an extension method or other static method to handle the null reference.
NullReferenceExceptions (NullPointerExceptions for the Javaheads; roughly synonymous) occur when code is told to call a method belonging to an object instance that doesn't actually exist. The thing you must keep in mind is that null is not actually any object. A variable of a type can be set to null, but that simply means the variable doesn't reference an instance.
Therein lies the problem; if a variable, regardless of its type (as long as that's a nullable type), is null, then there isn't an instance on which to call the method, and an instance is required for instance methods because that's how the program determines the state of members accessible to the method. If MyClass had a MyField and MyMethod(), and you called MyMethod on a null reference of MyClass, what's the value of MyField?
The solution is usually to move to static scope. Static members (and classes) are guaranteed to have state because they are instantiated once at runtime (usually just-in-time, as in before first reference). Because they always have state, they can always be called and so can be given things to do that may not be able to be done at the instance level. Here's a method you can use in C# to return a value from an object member chain which may otherwise result in an NRE:
public static TOut ValueOrDefault<TIn, TOut>(this TIn input, Func<TIn, TOut> projection,
TOut defaultValue = default(TOut))
{
try
{
var result = projection(input);
if (result == null) result = defaultValue;
return result;
}
catch (NullReferenceException) //most nulls result in one of these.
{
return defaultValue;
}
catch (InvalidOperationException) //Nullable<T>s with no value throw these
{
return defaultValue;
}
}
Usage:
class MyClass {public MyClass2 MyField;}
class MyClass2 {public List<string> MyItems; public int? MyNullableField;}
...
var myClass = null;
//returns 0; myClass is null
var result = myClass.ValueOrDefault(x=>x.MyField.MyItems.Count);
myClass = new MyClass();
//returns 0; MyField is null
result = myClass.ValueOrDefault(x=>x.MyField.MyItems.Count);
myClass.MyField = new MyClass2();
//returns 0; MyItems is null
result = myClass.ValueOrDefault(x=>x.MyField.MyItems.Count);
myClass.MyField.MyItems = new List<string>();
//returns 0, but now that's the actual result of the Count property;
//the entire chain is valid
result = myClass.ValueOrDefault(x=>x.MyField.MyItems.Count);
//returns null, because FirstOrDefault() returns null
var myString = myClass.ValueOrDefault(x=>x.MyField.MyItems.FirstOrDefault());
myClass.MyField.MyItems.Add("A string");
//returns "A string"
myString = myClass.ValueOrDefault(x=>x.MyField.MyItems.FirstOrDefault());
//returns 0, because MyNullableField is null; the exception caught here is not an NRE,
//but an InvalidOperationException
var myValue = myClass.ValueOrDefault(x=>x.MyField.MyNullableField.Value);
While this method has value in situations which would otherwise call for long nested ternary operators to produce something (anything) to show the user or use in a calculation, I do NOT recommend using this pattern to perform actions (void methods). Because no NREs or IOEs will be thrown out, you'll never know if what you asked it to do was actually done. You may be able to get away with a "TryPerformAction()" method which returns true or false, and/or has an output parameter containing the thrown exception (if any). But if you're going to go to that kind of trouble, why not just try/catch the thing yourself?
Why does the C# compiler not even complain with a warning on this code? :
if (this == null)
{
// ...
}
Obviously the condition will never be satisfied..
Because you could override operator == to return true for that case.
public class Foo
{
public void Test()
{
Console.WriteLine(this == null);
}
public static bool operator ==(Foo a, Foo b)
{
return true;
}
public static bool operator !=(Foo a, Foo b)
{
return true;
}
}
Running new Foo().Test() will print "True" to the console.
The other question here is: why doesn't the compiler issue a warning for ReferenceEquals(this, null)? From the bottom of the above link:
A common error in overloads of operator == is to use (a == b), (a == null), or (b == null) to check for reference equality. This instead results in a call to the overloaded operator ==, causing an infinite loop. Use ReferenceEquals or cast the type to Object, to avoid the loop.
That might be answered by #Aaronaught's response. And that's also why you should be doing (object)x == null or ReferenceEquals(x, null), not doing a simple x == null, when you're checking for null references. Unless, of course, you're sure that the == operator is not overloaded.
Wow... I guess I was shamefully wrong
I disagree. I think you still make a good point.
The compiler knows whether the comparison is going to go to a user-defined comparison operator or not, and the compiler knows that if it does not, then 'this' is never null.
And in fact, the compiler does track whether a given expression can legally be null or not, in order to implement a minor optimization on non-virtual method calls. If you have a non-virtual method M and you say foo.M(); then the compiler generates this as "do a virtual call to M with receiver foo". Why? Because we want to throw if foo is null, and a virtual call always does a null check on the receiver. A non-virtual call does not; we'd have to generate it as "check foo for null, and then do a non-virtual call to M", which is longer, slower, more irritating code.
Now, if we can get away without doing the null check, we do. If you say this.M() or (new Foo()).M() then we do NOT generate a virtual call. We generate the non-virtual call without the null check because we know that it cannot be null.
So the compiler has excellent data on whether a particular comparison to null will sometimes, always, or never succeed.
The question then is "if the compiler knows that a particular comparison will never succeed, why not generate a warning for it?"
And the answer is "sometimes we do, and sometimes we don't".
We do in this situation:
int x = 123;
if (x == null) ...
There is an equality operator defined on two nullable ints. x is convertible to nullable int. null is convertible to nullable int. So that equality operator is valid, and therefore is used, and is of course always false. The compiler gives a warning that the expression is always false.
However, due to a bug we accidentally introduced in C# 3, this code does NOT produce that warning:
Guid x = whatever;
if (x == null) ...
Same deal. The nullable guid equality operator is valid, but the warning is suppressed. I'm not sure if we fixed this bug for C# 4 or not. If not, hopefully we'll get it into a service pack.
As for "if (this == null)" I don't know why we don't warn for that. It certainly seems like a good candidate for a warning. The most likely explanation is to follow this logical syllogism:
warnings are compiler features
compiler features must be (1) thought of, (2) designed, (3) implemented, (4) tested, (5) documented and (6) shipped to you before you can take advantage of the feature.
No one has done any of those six necessary things for this feature; we can't ship features that we never thought of in the first place.
therefore, no such feature.
There are infinitely many compiler features that we haven't thought of yet; we've implemented none of them.
Another reason to not give a warning here is that we try to give warnings on code which is both likely to be typed by accident and almost certainly wrong for a non-obvious reason. "this == null" is not likely to be typed in by accident, and though it is almost certainly wrong, as you note in the statement of your question, it is obviously wrong.
Compare that to our "guid == null" -- that is likely to happen by accident, because a developer might accidentally think that Guid is a reference type. Guids are usually passed around by reference in C++, so this is an easy mistake to make. The code is almost certainly wrong, but it is wrong in a non-obvious way. So this is a good candidate for a warning. (Which is why it is so unfortunate that this is a warning in C# 2 but not C# 3, due to a bug we introduced.)
Actually, the condition really can be satisfied, at least in Visual Studio 2008. They've fixed this behaviour in VS 2010, but it is not totally inconceivable that there might be another way to create such a condition.
(tl;dr version - in C# 3.5, it's legal to reference this from an anonymous function passed as a constructor argument, but if you actually try to use it, you'll find that this is null.)
Though the code below is a bastard it's still all C#. an if you call Bar you will get an InvalidOperationException with the message null.
public class Foo
{
static Action squareIt;
static Foo() {
var method = new DynamicMethod(
"TryItForReal",
typeof(void),
Type.EmptyTypes,
typeof(Foo).Module);
ILGenerator il = method.GetILGenerator();
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Call, typeof(Foo).GetMethod("tryit"));
il.Emit(OpCodes.Ret);
squareIt = (Action)method.CreateDelegate(typeof(Action));
}
public void tryit()
{
if (this == null) {
throw new InvalidOperationException("Was null");
}
}
public void Bar() {
squareIt();
}
}
This also falls in line with other warnings C# does (or not does for that matter) like:
if(true)
or
if(1 == 1)
These will also always have the same result no matter what.
This question already has answers here:
Closed 14 years ago.
Duplicate: Function overloading by return type?
Maybe this is a very silly question but I don't understand why I can't declare two methods that have the same signature when they have different return types.
public class MyClass
{
private double d = 0;
public double MyMethod()
{
return d;
}
public string MyMethod()
{
return d.ToString();
}
}
I get a compile error that states that the class already defines a member with the same parameter types.
(Obviously the way I'm using this in my code isn't as simple as my example code...but I think it gets the idea across.)
Am I missing something concerning OO design that makes what I'm trying to do an OOP anti-pattern? Surely the compiler should be able to determine which method I'm trying to use as long as I specifically tell it which one I want.
Given MyClass myClass = new MyClass(); I would expect the following code to work:
double d = myClass.MyMethod();
string s = myClass.MyMethod();
I would expect the following code to have problems:
var v = myClass.MyMethod();
But even in the case of var it should result in a compile error.
Can anyone see what I'm doing wrong here? I'm more than happy to be corrected. :-)
It's because of type coercion.
Say you have the following functions:
int x(double);
float x(double);
double y = x(1.0);
Now, which of the two prototypes should you call, especially if they do two totally different things?
Basically, a decision was made early on in the language design to only use the function name and arguments to decide which actual function gets called, and we're stuck with that until a new standard arrives.
Now, you've tagged your question C# but I see nothing wrong with designing a language that can do what you suggest. One possibility would be to flag as an error any ambiguous commands like above and force the user to specify which should be called, such as with casting:
int x(double);
float x(double);
double y = (float)(x(1.0)); // overload casting
double y = float:x(1.0); // or use new syntax (looks nicer, IMNSHO)
This could allow the compiler to choose the right version. This would even work for some issues that other answers have raised. You could turn the ambiguous:
System.out.Println(myClass.MyMethod());
into the specific:
System.out.Println(string:myClass.MyMethod());
This may be possible to get added to C# if it's not too far into a standards process (and Microsoft will listen) but I don't think much of your chances getting it added to C or C++ without an awfully large amount of effort. Maybe doing it as an extension to gcc would be easier.
There's nothing from stopping you from calling your method without "capturing" the return type. There's nothing from stopping you from doing this:
myClass.MyMethod();
How will the compiler know which one to call in that case?
Edit: Adding to that, in C# 3.0, when you can use var, how will the compiler know which method you're calling when you do this:
var result = myClass.MyMethod();
Because the return type isn't all that important when calling a method. It would lead to ambiguity in many cases to have methods only differing by return type. You might not store the result in a variable at all, or do something like this:
System.out.Println(myClass.MyMethod());
The compiler would have no way to figure out, which of the methods you wanted to call.
A method signature is the name and input parameters (type & order) only. The return type is not part of the signature. Thus two methods with the same name and input parameters are identical and conflict with each other.
What, if any, variable you're assigning the method to can't inform the compiler which method to use. Imagine:
String message = "Result = " + myClass.MyMethod();