I'm trying to get runtime multiple inheritance to work using impromptu-interface but I'm stuck when I want to pass the object along to a method.
public interface IEngine {
void Foo();
}
public interface IWheels {
void Foo();
}
public interface IChassie {
void Foo();
}
public interface IPaintShop {
void PaintWheels(IWheels wheels);
void PaintChassie(IChassie chassie);
void ChromeEngine(IEngine engine);
}
var paintShop = Impromptu.ActLike<IPaintShop>();
var car = Impromptu.ActLike(new [] {typeof(IEngine), typeof(IWheels), typeof(IChassie) } );
// dynamic car = Impromptu.ActLike(new [] {typeof(IEngine), typeof(IWheels), typeof(IChassie) } ); // Same error
paintShop.PaintWheels(car); // RuntimeException as car is dynamic and not the expected IWheels
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : The best overloaded method match for 'MyStuff.PaintWheels(IWheels)' has some invalid arguments
I've tried to cast but get InvalidCastException
:
paintShop.PaintWheels((IWheels)car);
System.InvalidCastException : Unable to cast object of type 'ImpromptuInterface.ActLikeCaster' to type 'MyStuff.IWheels'.
The following works but I'm not sure this is the correct way; it seem unwarranted to convert car to IWheels
when IWheels
interface should already be inherited:
var wheels = Impromptu.CoerceConvert(car, typeof (IWheels));
paintShop.PaintWheels(wheels);
What is the correct way of achieving runtime multiple inheritance using impromptu-interface?
The issues you are running into are all related to type safety--even when using a library like Impromptu, you have to be sure the compiler and the runtime are sure the object you are passing into the method is the type that method requires.
ActLike<T>
can implement many interfaces, but it only returns a single typed instance ofT
, so without a type that tells the compiler that your instance implements several interfaces, you will be forced to cast to the necessary interfaces.Also, ImpromptuInterface allows you to wrap an object with an interface that informally matches up with the implementation of that object, even if the interface was not formally declared. As a consumer of that library, you still have to provide the implementations for the library to wrap.
Try something like the following: