3

(entlib 4 のポリシー インジェクション アプリケーション ブロックを使用して) クラスに適用されたカスタム ハンドラーがあり、Invoke が呼び出されたときに入力メソッドがプロパティであるかどうかを知りたいです。以下は、私のハンドラーがどのように見えるかです。

[ConfigurationElementType(typeof(MyCustomHandlerData))]
public class MyCustomHandler : ICallHandler
{
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        if (input.MethodBase.IsPublic && (input.MethodBase.Name.Contains("get_") || input.MethodBase.Name.Contains("set_")))
        {
            Console.WriteLine("MyCustomHandler Invoke called with input of {0}", input.MethodBase.Name);
        }
        return getNext().Invoke(input, getNext);
    }

    public int Order { get; set; }
}

コード サンプルからわかるように、これまでに考えた最善の方法は、メソッド名を解析することです。これを行うより良い方法はありませんか?

4

5 に答える 5

4

IsSpecialName が true であることも確認できます。これはプロパティに当てはまります(とりわけ)

il レベルでは、メソッドは次のように公開されます (例として Environment.ExitCode を使用)。

.method public hidebysig specialname static int32 get_ExitCode() cil managed
.method public hidebysig specialname static void set_ExitCode(int32 'value') cil managed

派手になりたい場合は、名前を抽出した後に、そのプロパティが存在することを確認できますが、正直に言うと

if (m.IsSpecialName && (m.Attributes & MethodAttributes.HideBySig) != 0)) 

get_ または set_ で始まるだけでなく、厄介な名前を使用している人にも適しているはずです (hidebysig を偽造するのは簡単ですが、IsSpecialName を偽造するのは非常に難しいでしょう)。

ただし、何も保証されません。誰かが、実際の set メソッドのように見える set_Foo メソッドを含むクラスを発行することができましたが、実際には読み取り専用プロパティのセットではありませんでした。プロパティ CanRead/CanWrite もチェックしない限り。

あなたは意図的な回避を期待していませんが、これはあなたにとって狂気のように私には思えます。このロジックを実行する MethodInfo の単純なユーティリティ/拡張メソッドはそれほど難しくなく、IsSpecialName を含めることでほぼ確実にすべてのニーズをカバーできます。

于 2008-09-16T15:58:19.127 に答える
0

IsSpecialName プロパティを確認できます。プロパティのゲッターとセッターについても同様です。ただし、演​​算子のオーバーロードなど、他の特別なメソッドにも当てはまります。

于 2008-09-16T15:42:58.630 に答える
0

私はそのアプリケーション ブロックに詳しくありませんが、MethodBase プロパティが System.Reflection.MethodBase 型であると仮定すると、IsSpecialName プロパティを調べることができます。

MSDN の System.Reflection.MethodBase.IsSpecialName

于 2008-09-16T15:46:27.967 に答える
0

MethodBase 型の「IsSpecialName」プロパティの使用について言及された方が 2 人います。がプロパティ「gets」または「sets」に対して true を返すのは事実ですが、add_EventName や remove_EventName などの演算子のオーバーロードに対しても true を返します。そのため、MethodBase インスタンスの他の属性を調べて、プロパティ アクセサーかどうかを判断する必要があります。残念ながら、MethodBase インスタンスへの参照しかない場合 (Unity フレームワークで動作をインターセプトする場合に当てはまると思います)、それがプロパティ セッターまたはゲッターであるかどうかを判断する真の「クリーンな」方法はありません。私が見つけた最良の方法は次のとおりです。

C#:

bool IsPropertySetter(MethodBase methodBase){
     return methodBase.IsSpecialName && methodBase.Name.StartsWith("set_");
}

bool IsPropertyGetter(MethodBase methodBase){
     return methodBase.IsSpecialName && methodBase.Name.StartsWith("get_");
}

VB:

 Private Function IsPropertySetter(methodBase As MethodBase) As Boolean

      Return methodBase.IsSpecialName AndAlso methodBase.Name.StartsWith("set_")

 End Function

 Private Function IsPropertyGetter(methodBase As MethodBase) As Boolean

      Return methodBase.IsSpecialName AndAlso methodBase.Name.StartsWith("get_")

 End Function
于 2014-06-08T02:55:06.953 に答える