【问题标题】:How do I/can I dynamically extend a c# object with methods that exist on another object?我/我如何使用另一个对象上存在的方法动态扩展 c# 对象?
【发布时间】:2014-04-02 11:21:09
【问题描述】:

假设我有一个对象a,它属于A类:

abstract class A {
    public abstract SomeType SomeMethod(int i)
    public abstract SomeType SomeOtherMethod()
}

我可以/我如何创建一个 B 类的对象 b - 在运行时,它可以获取任何对象(比如 A)并包装它:

class B {
   public void Wrap(object someObject) {}
}

这样我就可以编写以下代码:

var a = Factory.BuildAn<A>();
var b = new B();
b.Wrap(a);
b.SomeMethod(1);

【问题讨论】:

标签: c# reflection


【解决方案1】:

我不确定你想用这个解决什么问题,但这就是你问的问题。

class MyClass
{
    public int IntValue { get; set; }

    public string SomeMethod(int i)
    {
        return i.ToString();
    }
    public string SomeOtherMethod()
    {
        return "Hello";
    }
}

class Wrapper : DynamicObject
{
    private object wrappedObject;

    public Wrapper(object wrappedObject)
    {
        this.wrappedObject = wrappedObject;
    }

    private void Wrap(object someObject)
    {
        wrappedObject = someObject;
    }


    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        PropertyInfo prop = wrappedObject.GetType()
            .GetProperty(binder.Name, BindingFlags.Instance | BindingFlags.Public);
        if (prop == null)
        {
            result = null;
            return false;
        }

        result = prop.GetValue(wrappedObject, null);
        return true;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        PropertyInfo prop = wrappedObject.GetType()
            .GetProperty(binder.Name, BindingFlags.Instance | BindingFlags.Public);
        if (prop == null)
        {
            return false;
        }

        prop.SetValue(wrappedObject, value);
        return true;
    }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        MethodInfo method = wrappedObject.GetType()
            .GetMethod(binder.Name, BindingFlags.Instance | BindingFlags.Public);
        if (method == null)
        {
            result = null;
            return false;
        }

        result = method.Invoke(wrappedObject, args);
        return true;
    }
}

MyClass a = new MyClass();
dynamic d = new Wrapper(a);
d.IntValue = 5;
string s = d.SomeOtherMethod();
Console.WriteLine(a.IntValue);

【讨论】:

    【解决方案2】:

    是的,您可以在 C# 中使用动态类型。 B 类看起来像这样,您将完全按照您在问题中使用它的方式使用它。

    class B : DynamicObject
    {
        object _object;
        public void Wrap(object someObject)
        {
            _object = someObject;
        }
    
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            try
            {
                result = _object.GetType().InvokeMember(
                    binder.Name,
                    BindingFlags.InvokeMethod |
                    BindingFlags.Public |
                    BindingFlags.Instance,
                    null, _object, args);
                    return true;
            }
            catch
            {
                result = null;
                return false;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-15
      • 2011-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多