如果是这样,我非常想使用它。有人有任何指示吗?
我的目标是在我的测试解决方案中消除对 _accessor 项目的需求。我想如果我创建了一个动态类,应该可以记录应用了哪些函数,然后使用反射在另一个对象上重放这些函数。通过反射,我们可以调用私有函数。(我想要 C++ 的#define private public 的 C# 变体。)
我想我自己可以做到这一点,但是如果我可以重用一些代码,为什么要这样做。
如果是这样,我非常想使用它。有人有任何指示吗?
我的目标是在我的测试解决方案中消除对 _accessor 项目的需求。我想如果我创建了一个动态类,应该可以记录应用了哪些函数,然后使用反射在另一个对象上重放这些函数。通过反射,我们可以调用私有函数。(我想要 C++ 的#define private public 的 C# 变体。)
我想我自己可以做到这一点,但是如果我可以重用一些代码,为什么要这样做。
如果您想将其用于单元测试,请考虑更改您的单元测试方法。如果您深入到每个私有方法,您的测试与实际实现非常紧密地耦合在一起。
使用这种方法的常见问题是
每次你必须重构一些代码时,你也必须更改一堆测试。由于修复所有破坏性测试需要时间和痛苦,这将对重构造成巨大障碍。您甚至冒着创建不良行为的风险,因为您必须更改太多测试以改变原始行为。
我建议编写测试来测试你的类的行为。如果您更改实现此行为的方式,您将根本不会破坏测试并确认您的重构没有改变整体行为。
您的测试将更加清晰,并指定设计中真正重要的部分。这在重构时很有帮助,或者如果有人(甚至可能是几个月后的你)必须再次进入代码。
您可以使用扩展来动态访问每个私有函数。
public static class ObjectEx
{
public static object CallPrivateFunc(this object obj,string funcName, params object[] args)
{
const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod;
return obj.GetType().InvokeMember(funcName, bindingFlags, null, obj, args);
}
}
那里的用法:
public class MyClass
{
private void MyFunc(int a,string c)
{
Trace.WriteLine("MyFunc called a:" + a + " c:" + c);
}
}
...
myClass.CallPrivateFunc("MyFunc", 10, "c");
...
我尝试自己创建类,这种代码是否适用于方法调用:
public class UnPrivatify : DynamicObject
{
private object _obj;
public UnPrivatify(object obj)
{
_obj = obj;
}
public override bool TryInvokeMember(
InvokeMemberBinder binder,
Object[] args,
out Object result)
{
Type t = _obj.GetType();
result = t.InvokeMember(binder.Name,
System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public,
null,
_obj,
args);
return true;
}
}
apache 许可的Impromptu 接口具有静态函数,这些函数使用 DLR 通过 binder.name 调用方法或属性,以确定它是否是私有的。在 DynamicObject 中调用它们应该很容易。
http://code.google.com/p/impromptu-interface/wiki/UsageReallyLateBinding
编辑:
在最新发布的 4.0 版中,有一个抽象类ImpromptuForwarder,如果您创建一个没有更改的普通子类,它将动态调用转发到目标中的私有方法/属性。