在.NET 4.0(C#)中动态实现接口

借助.NET 4.0中的新动态功能,似乎应该有可能动态实现一个接口,例如 给出:

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

但是,到目前为止,我不确定用什么替换// something clever goes here

因此,我的问题是:

  1. 这实际上与动态运行时有关吗? 动态实现方法和属性之类的东西似乎很容易,但是我还没有找到任何有关动态实现接口和对其进行转换的文档。

  2. 假设这是可能的,那么可能会有多困难? (您可以假设我是一个体面的程序员,对反射之类的东西有丰富的经验,但是对于动态框架却是新知识。)

  3. 是否有任何资源可以帮助我指出实施此类目标的正确方向? 甚至是已经完成此类事情的样本,我都可以以此为起点?

Greg Beech asked 2020-07-04T05:56:40Z
5个解决方案
44 votes

开源框架Impromptu-Interface就是为此目的而设计的。 它生成缓存的轻量级具有静态接口的代理,并使用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);
jbtule answered 2020-07-04T05:57:20Z
14 votes

据我所知,没有人工干预就不可能编写或生成将接口成员转发到包装实例的代码。 如果您希望看到Microsoft为此类事情提供的支持,则可能需要考虑在[https://connect.microsoft.com/VisualStudio/feedback/details/526307/add-automatic-generation-of- 通过接口实现成员]。

Nicole Calinoiu answered 2020-07-04T05:56:56Z
7 votes

我想我写了一个库,它可以满足您的需求……它被称为DynamicWrapper(在CodePlex上),它将自动包装一个类,从而实现一个接口。 这是你想要的吗?

Brian Genisio answered 2020-07-04T05:57:41Z
3 votes

显式转换asis由于类型比较会与您的代理基类相对而失败,但是隐式转换可以触发DynamicObject.TryConvert,这样您就可以返回动态对象的内部对象。
-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;

    }

}
stephbu answered 2020-07-04T05:58:10Z
3 votes

为了补充@jbtule的答案,我创建了CustomActivator,它能够在运行时创建动态对象并使其实现所需的接口。 我还使用Impromptu-Interface框架来完成该任务。

调用很简单:

CustomActivator.CreateInstance<MyInterface>();

我把它放在github上。

fabriciorissetto answered 2020-07-04T05:58:39Z
translate from https://stackoverflow.com:/questions/2974736/dynamically-implementing-an-interface-in-net-4-0-c