I have the following code:
class Program
{
static void Main(string[] args)
{
var first = new A();
OtherClass.EnjoyLife(new OtherClass(first), OtherClass.Default);
Console.ReadKey();
}
public interface IInterface
{
void DoStuff(IInterface obj);
}
public abstract class AbstractBaseClass<T> : IInterface where T : AbstractBaseClass<T>
{
internal abstract void DoStuff(T obj);
void IInterface.DoStuff(IInterface obj) => DoStuff((T)obj);
}
public class A : AbstractBaseClass<A>
{
internal override void DoStuff(A obj)
{
Console.WriteLine($"Do {obj}");
}
}
public class B : AbstractBaseClass<B>
{
internal override void DoStuff(B obj)
{
Console.WriteLine($"Do {obj}");
}
public static explicit operator A(B obj) => new A();
}
public class OtherClass
{
public static readonly OtherClass Default = new OtherClass();
private IInterface foo;
private OtherClass()
{
this.foo = new B();
}
public OtherClass(IInterface bar)
{
this.foo = bar;
}
public static void EnjoyLife(OtherClass left, OtherClass right)
{
left.foo.DoStuff(right.foo);
}
}
}
When I run it, I have an InvalidCastException: 'Unable to cast object of type 'B' to type 'A'.'
being thrown when the explicit implementation of DoStuff
is executed on AbstractBaseClass<T>
. Why is it so even if an explicit cast from B
to A
is implemented on B
?
Quite interestingly, if I replace
void IInterface.DoStuff(IInterface obj) => DoStuff((T)obj);
by
void IInterface.DoStuff(IInterface obj) => DoStuff((T)obj.GetType().GetMethod("op_Explicit").Invoke(null, new[] { obj }));
then it works perfectly fine. But I cannot this solution for other reasons. I know the code is a bit circumvented but I don't see any reason why this should not work.