Reputation: 292
In a generic method you need to cast your return variable to an object and then back to the generic type and I understand why that is generally, but what I don't understand is why you need to do that when you've already established what type the variable is in the scope of the return statement. For example, normally I'd do this:
public MyType1 obj1;
public MyType2 obj2;
public T GetObject<T>()
{
if (obj1 is T) return (T)(object)obj1;
else if (obj2 is T) return (T)(object)obj2;
else return default(T);
}
But my question is, why can't I remove the casting like this:
public MyType1 obj1;
public MyType2 obj2;
public T GetObject<T>()
{
if (obj1 is T) return obj1;
else if (obj2 is T) return obj2;
else return default(T);
}
Why doesn't the compiler understand that the object is of the correct return type when that's the only type it could be?
Upvotes: 1
Views: 140
Reputation: 155055
Avoid foo is T; (T)foo
expressions. Use the as
operator and it solves your problems:
public MyType1 obj1;
public T GetObject<T>() where T : class {
T ret = obj1 as T;
if( ret != null ) return ret;
ret = obj2 as T;
if( ret != null ) return ret;
return default(T);
}
Upvotes: 1
Reputation: 11788
According to the C# Reference:
The is keyword causes a compile-time warning if the expression is known to always be true or to always be false, but typically evaluates type compatibility at run time.
That is whether obj1
is of type T
is not determined by the compiler but is evaluated when the code runs.
Upvotes: 3
Reputation: 5443
You are making incorrect assumptions about generics. To understand this better, imagine this. Let's say you had a base class Base and two sub classes, Sub and VerySub.
If your members were stored as Base then the compiler can only guarantee they are Base. It is the static typing system which generics use. At run time let's say we had a simple function called GetIfVerySub. Let's say it did a test on an object of type Base and discovered it was also a VerySub. That's unknowable at compile time, so to return the downcasted object, you would expect to do a cast or an as.
This is exactly what your generic function is trying to do, but owing to the fact it is generic, it also can work on any type, including ones incompatible with Base.
The better question, though, is why you are doing this at all?
Upvotes: 3