I thought I had it with this...
//Interface
public interface IGreeting
{
void SayHelloTo(string name);
}
//Implementor
public class GreetingImpl : IGreeting
{
public void SayHelloTo(string name)
{
Console.WriteLine("Hello " + name);
}
}
//Some magic
public interface IWrappable<T>
{
T Wrapper { get; }
}
//The consuming class
public class MyClass1 : IWrappable<IGreeting>
{
#region Implements IGreeting
IGreeting IGreetingImpl = new GreetingImpl();
IGreeting IWrappable<IGreeting>.Wrapper
{
get { return IGreetingImpl; }
}
public static explicit operator IGreeting(MyClass1 instance)
{
return ((IWrappable<IGreeting>)instance).Wrapper;
}
#endregion
}
Looks a bit long winded, but easy enough to do with a template. However I get the following error...
"user-defined conversions to or from an interface are not allowed"
That's a shame, isn't it :) Although without the explicit/implicit casting you might still find this useful for passing an API interface to a Dynamic Runtime Language to stop it accessing a property defined as read-only in the interface as a read/write property by dynamically looking up the property on the implementing type.
public static class IWrappableHelper
{
public static TInterface GetWrapper<TSource, TInterface>(this TSource instance)
where TSource : IWrappable<TInterface>
where TInterface : class
{
if (instance == null)
return null;
return instance.Wrapper;
}
}
Then you can do this
var apiImpl = myClass1Instance.GetWrapper<MyClass1, IGreeting>();
//now pass apiImpl to the DLR instead of apiImpl