是否有人创建了一个开源动态.NET类,用于在另一个类上公开私有函数/属性?

时间:2011-04-10 21:02:59

标签: .net reflection dynamicobject

如果是这样,我非常想使用它。有人有任何指示吗?

我的目标是在我的测试解决方案中删除对_accessor项目的需求。我想如果我创建了一个动态类,应该可以记录应用于它的函数,然后使用反射在另一个对象上重放这些函数。通过反射,我们可以调用私有函数。 (我想要C ++的#define私有公共C#变体。)

我想我自己可以做到这一点,但为什么要重用一些代码呢?

4 个答案:

答案 0 :(得分:2)

如果您想将其用于单元测试,请考虑更改单元测试的方法。如果你深入到每个私有方法,你的测试与实际实现非常紧密。

使用这种方法的常见问题是

  • 非常脆弱且难以维持测试
  • 您的测试很可能会反映应用程序的行为和代码
  • 由于描述每个细节的数十个测试
  • ,因此您的类的基本行为并不明显

每次你必须重构一些代码时,你也必须改变一堆测试。由于修复所有破坏测试所需的时间和精力,这将对重构造成巨大障碍。您甚至冒着创建不良行为的风险,因为您必须更改原始行为更改的许多测试。

我建议编写测试类行为的测试。如果您改变了实现此行为的方式,则根本不会破坏测试并确认您的重构不会改变整体行为。

您的测试将更清晰,并指定您设计中非常重要的部分。这有助于重构,或者某些人(可能在几个月后甚至是你)必须再次进入代码。

答案 1 :(得分:1)

您可以使用扩展程序动态访问每个私有函数。

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

答案 2 :(得分:1)

我试图自己创建这个类,这个代码是否适用于方法调用:

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

答案 3 :(得分:0)

许可的apache Impromptu Interface具有静态函数,这些函数使用DLR通过binder.name调用方法或属性是否为私有方式。在DynamicObject中调用它们应该很容易。

http://code.google.com/p/impromptu-interface/wiki/UsageReallyLateBinding

修改

在最新发布的4.0版本中,有一个抽象类ImpromptuForwarder,如果您创建一个没有更改的普通子类,则会将动态调用转发给目标中的私有方法/属性。