2

もしそうなら、私はそれを非常に使いたいと思います。誰かがポインタを持っていますか?

私の目標は、テストソリューションで_accessorプロジェクトの必要性をなくすことです。動的クラスを作成した場合、それに適用されている関数を記録し、リフレクションを使用してこれらの関数を別のオブジェクトで再生できるはずだと考えました。そして、リフレクションを使用すると、プライベート関数を呼び出すことができます。(C++の#defineprivate publicのC#バリアントが必要です。)

自分でできると思いますが、コードを再利用できるのならなぜそうするのでしょうか。

4

4 に答える 4

2

これを単体テストに使用する場合は、単体テストへのアプローチを変更することを検討してください。すべてのプライベート メソッドに取り掛かると、テストは実際の実装に非常に緊密に結合されます。

このアプローチを使用した場合の一般的な問題は次のとおりです。

  • 非常に壊れやすく、テストを維持するのが難しい
  • テストは、アプリケーションの動作とコードを反映している可能性が非常に高いです
  • すべての詳細を説明する数十のテストがあるため、クラスの本質的な動作は明らかではありません

コードをリファクタリングする必要があるたびに、一連のテストも変更する必要があります。これは、すべての破壊的なテストを修正するのに時間と労力がかかるため、リファクタリングに対する大きな障壁となります。元の動作が変更されるほど多くのテストを変更する必要があるため、望ましくない動作を作成するリスクさえあります。

クラスの動作をテストするテストを作成することをお勧めします。この動作を実現する方法を変更すると、テストがまったく中断されず、リファクタリングによって全体的な動作が変更されていないことが確認されます。

テストはより明確になり、設計の本当に重要な部分を指定します。これは、リファクタリングするとき、または誰か (数か月後にあなたでさえ) がコードに再度アクセスする必要がある場合に役立ちます。

于 2011-04-10T21:20:10.677 に答える
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");
...
于 2011-04-10T22:17:18.260 に答える
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;
    }
}
于 2011-04-10T22:35:17.657 に答える
0

apache ライセンスのImpromptu Interfaceには、DLR を使用してメソッドまたはプロパティを呼び出す静的関数があり、binder.name を介してプライベートであるかどうかに関係します。DynamicObject 内でそれらを呼び出すのは非常に簡単です。

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

編集

最新リリースのバージョン 4.0 には、抽象クラスImpromptuForwarderがあり、変更のない単純なサブクラスを作成すると、動的呼び出しがターゲットのプライベート メソッド/プロパティに転送されます。

于 2011-04-12T04:25:11.123 に答える