代码之家  ›  专栏  ›  技术社区  ›  Greg Beech

在.NET4.0(C#)中动态实现接口

  •  43
  • Greg Beech  · 技术社区  · 15 年前

    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. 有没有什么资源可以帮助我朝着正确的方向去实现这样的东西?或者甚至是已经做过这种事情的样本,我可以用它们作为出发点?

    5 回复  |  直到 15 年前
        1
  •  14
  •   Nicole Calinoiu    15 年前

    据我所知,如果没有手动干预,编写或生成将接口成员转发到包装实例的代码是不可能的。如果你想看到微软为这类事情提供支持,你可以考虑在 https://connect.microsoft.com/VisualStudio/feedback/details/526307/add-automatic-generation-of-interface-implementation-via-implementing-member

        2
  •  46
  •   jbtule    12 年前

    开源框架 Impromptu-Interface 是设计来做这个的。它生成一个缓存的轻量级

    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);
    
        3
  •  6
  •   Brian Genisio    15 年前
        4
  •  3
  •   Jordão    15 年前

    显式铸造, as ,和 is
    - TryConvert MSDN Documentation

    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;
    
        }
    
    }
    
        5
  •  3
  •   fabriciorissetto    11 年前

    作为对@jbtule答案的补充,我创建了CustomActivator,它能够在运行时创建动态对象,并使其实现所需的接口。我也使用 Impromptu-Interface framework

    电话很简单:

    CustomActivator.CreateInstance<MyInterface>();
    

    我穿上了 github .