在.NET 4.0中dynamic实现接口(C#)
使用.NET 4.0中的新dynamicfunction,似乎应该可以dynamic地实现一个接口,例如:
public interface IFoo { string Bar(int baz); } public class Foo : IFoo { public string Bar(int baz) { return baz.ToString(); } } public class Proxy : IDynamicMetaObjectProvider { private readonly object target; public Proxy(object target) { this.target = target; } // something clever goes here }
那么我希望有一些方法可以写出来:
dynamic proxy = new Proxy(new Foo()); IFoo fooProxy = (IFoo)proxy; // because the target object implements it string bar = fooProxy.Bar(123); // delegates through to the target implementation
但是,到目前为止,我还不确定要replace// something clever goes here
。
所以,我的问题是:
-
这实际上可以做到dynamic运行时? 看来dynamic地实现诸如方法和属性之类的东西相当容易,但是我还没有find任何有关dynamic实现接口和转换的文档。
-
假设这是可能的,它有多难? (你可以假设我是一个体面的程序员,有很多像反思这样的东西,但是对于dynamic框架来说是新的。)
-
有没有什么资源可以帮助我指出正确的方向来执行这样的事情? 或者甚至是这样的事情已经完成,我可以作为一个起点的样本?
据我所知,没有人工干预就不可能编写或生成将接口成员转发给包装实例的代码。 如果你想看到微软提供的这种支持,你可以考虑投票在https://connect.microsoft.com/VisualStudio/feedback/details/526307/add-automatic-generation-of-interface -implementation-via-implementation-member 。
开源框架Impromptu-Interface被devise来做到这一点。 它生成一个带有静态接口的caching轻量级代理,并使用dlr将调用转发给原始对象。
using ImpromptuInterface; public interface ISimpeleClassProps { string Prop1 { get; } long Prop2 { get; } Guid Prop3 { get; } }
–
dynamic tOriginal= new ExpandoObject(); tOriginal.Prop1 = "Test"; tOriginal.Prop2 = 42L; tOriginal.Prop3 = Guid.NewGuid(); ISimpeleClassProps tActsLike = Impromptu.ActLike(tOriginal);
我想我写了一个你想要的库…它被称为DynamicWrapper(在CodePlex上),它会自动包装一个类,所以它实现了一个接口。 这是你想要的吗?
显式强制转换,因为types比较会导致代理基类失败,但是隐式强制转换可以触发DynamicObject.TryConvert,这样就可以返回内部对象代替dynamic对象。
– TryConvert MSDN文档
虽然下面的代码工作,这不是接口委托本身,只暴露内部状态。 这听起来像你可能正在寻找像Brian的DynamicWrapper这样的拦截模式。
dynamic wrapper = new Proxy(new Foo()); IFoo foo = wrapper; foo.Bar(); class Proxy : DynamicObject { ... public override bool TryConvert(ConvertBinder binder, out object result) { Type bindingType = binder.Type; if (bindingType.IsInstanceOfType(target)) { result = target; return true; } result = null; return false; } }
从@jbtule补充答案我创build了我的CustomActivator,它能够在运行时创build一个dynamic对象,并使其实现所需的接口。 我也使用Impromptu-Interface框架来实现这一点。
电话很简单:
CustomActivator.CreateInstance<MyInterface>();
我把它放在github上 。