我/是否可以使用另一个对象上存在的方法动态扩展 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);
不确定您要解决此问题,但这就是您提出的问题。
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;
}
}
}