我有一个继承自DynamicObject
的班级
在这个课程中,我有一个TryGetMember
我尝试评估一个静态类。
TryGetMember
如何覆盖DynamicObject
会导致静态类?
TL; DR
致电代码:
dynamic sut = new ReachIn();
sut.myclass.MyInnerStaticClass.MyProperty= "fortytwo";
我的DynamicObject
类尝试将myclass
作为MyClass
实例返回。
internal class ReachIn : DynamicObject
{
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = MyClass; // Does not compile.
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
value = MyClass // Does not compile;
return true;
}
}
返回的是:
internal class MyClass
{
internal static class MyInnerStaticClass
{
public static string MyProperty { get; set; }
}
}
这个例子有点强迫。它只是动态对象的 very 简化示例,使得私有字段,属性,方法(和(尚未)类)可用于测试目的。我也知道不应该用这种方式写测试,但我有一个深奥的理由。或者因为我可以。
答案 0 :(得分:2)
无论你的课堂设计如何,我都会表明你想要实现的是动态类型和反射。首先,动态对象只是一个对象,可以在TryGetMember
等方法中使用某些字符串名称来执行某些操作。其次,使用字符串名称和反射,您可以对对象执行任何操作。如此简单的动态对象实现将与您的示例一起使用,如下所示:
internal class ReachIn : DynamicObject
{
private readonly Type type;
private readonly string @namespace;
public ReachIn(Type type = null, string @namespace = null)
{
this.type = type;
this.@namespace = @namespace;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (type == null)
{
result = new ReachIn(Type.GetType($"{@namespace}.{binder.Name}".Trim('.')));
return true;
}
var member = type.GetMember(binder.Name).Single();
if (member.MemberType == MemberTypes.NestedType)
{
result = new ReachIn((Type)member);
}
else if (member.MemberType == MemberTypes.Property)
{
result = ((PropertyInfo)member).GetValue(null);
}
else
{
result = null;
return false;
}
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
var member = type.GetMember(binder.Name).Single();
if (member.MemberType == MemberTypes.Property)
{
((PropertyInfo)member).SetValue(null, value);
return true;
}
return false;
}
}
因此它适用于具有公共修饰符的示例类:
public class MyClass
{
public static class MyInnerStaticClass
{
public static string MyProperty { get; set; }
}
}
使用此功能,您可以设置静态属性,如:
dynamic sut = new ReachIn(@namespace: "ConsoleApp8");
sut.MyClass.MyInnerStaticClass.MyProperty = "safd";
它仅针对您的示例进行了测试,因此对于其他情况,您需要提供一些额外的实现。更不用说它的表现因为反思而非常糟糕。