My situation:
interface ISomeInterface {
void DoSmth<T>(T other);
}
class Base : ISomeInterface
{
public virtual void DoSmth<T>(T other){
// for example do nothing
}
}
class Derived<T2> : Base {
Action<T2> MyAction {get;set;}
public override void DoSmth<T>(T other){
if(typeof(T2).IsAssignableFrom(typeof(T)))
MyAction((T2) other);
}
}
This gives me an error: Cannot cast expression of type 'T' to type 'T2'
(or Cannot convert type 'T' to 'T2'
)
I understand that it is because neither T or T2 are constrained with class
, but if I know - due to IsAssignableFrom
- that I can use T where I need T2, how can I convince compiler to allow it?
The compiler sees the T2 and T identifiers and helpfully informs you that those types seem unrelated. That's absolutely correct, as they have no relation: there are no generic constraints that would assert any relations between them (I'm not saying that would be useful here though :) ).
Whether this is a good feature or not, is disputable. Sometimes I'd like it to be just a warning, but in most cases, it's helpful to have it be a compilation error. Number of such casts in generic classes is much lower than number of typos in 'normal' code :)
Solution is very very simple. Just cheat the compiler to know nothing about the source type, and it will skip the type hierarchy checks against destination type:
T theTee = ...;
object temp = (object)theTee;
T2 teeTwo = (T2)temp; // ok! 'temp' is now seen as 'object'
or in one liner:
T2 teeTwo = (T2)(object)theTee;
similarly, you can use dynamic
(if it's available at your .Net version):
T theTee = ...;
dynamic temp = theTee;
T2 teeTwo = temp;
and oneliner should work too:
T2 teeTwo = (dynamic)theTee;
though I have never tried that one, as I think it's heavier than cast-via-object. I haven't checked performance of object/dynamic approaches though. Just a hunch.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With