假设我有一个对象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);
答案 0 :(得分:3)
我不确定你用这个问题试图解决什么问题,但这就是你问的问题。
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);
答案 1 :(得分: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;
}
}
}