我/是否可以使用另一个对象上存在的方法动态扩展 c# 对象

本文关键字:方法 动态 扩展 对象 存在 是否 可以使 一个对象 | 更新日期: 2023-09-27 17:55:57

假设我有一个对象 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# 对象

不确定您要解决此问题,但这就是您提出的问题。

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);

是的,您可以在 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;
        }
    }
}
相关文章: