2011-10-19 3 views
10

Castle DynamicProxy을 사용하여 데코레이션 프록시를 쓰고 있습니다.MethodInfo 인스턴스가 속성 접근 자인지 식별 ​​

public void Intercept(IInvocation invocation) 
{ 
    if (invocation.Method.Name.StartsWith("set_") 
    { 
     // ... 
    } 

    invocation.Proceed(); 
} 

을 지금이 잘 작동하지만 난 내 프록시의 친밀한 지식을 가지고 사실을 좋아하지 않는다 : 나는 내가 thusly 히 메소드의 이름을 확인하고 전용 속성 (안 읽고) 글을 차단하도록 프록시의 인터셉터가 필요합니다 속성이 구현되는 방식 : 메소드 이름 확인을 다음과 비슷한 것으로 대체하고 싶습니다.

if (invocation.Method.IsPropertySetAccessor) 

불행히도 내 Google-fu는 실패했습니다. 어떤 아이디어?

답변

15

당신은 속성이 방법은 (안된) 세터 인 존재 여부를 확인할 수 있습니다 : (. 영감 Marc's answer to a related question에서 촬영)

bool isSetAccessor = invocation.Method.DeclaringType.GetProperties() 
     .Any(prop => prop.GetSetMethod() == invocation.Method) 

+1

매우 열악합니다. – thepirat000

+0

@ thepirat000 : 음,'GetSetMethod'가 O (1)이면 O (n)이됩니다. 그게 아마도 최적이 아니에요. (똑같이 읽을 수 있고 더 나은 성능을내는 답을 분명히 upvote 할 것입니다.)하지만, 모든 악의 근원이되는 조숙 한 최적화에 대한 말을 알고있을 것입니다 ... – Heinzi

+0

나는 메소드가 "get_"접두사 (casesensitive)를 가지고 메소드 콜렉션 (여전히 O (n) 복잡성 - 오히려 싸다)에서 그것을 제거하는지 확인한다. 추가적으로'Dictionary '인스턴스를 추가하여 O (n)의 복잡성을 제공하지만 나중에 O (1) –

-4

난 당신이 확장 방법을 사용하려고 할 수 있습니다 생각 : 나는 알고 있어요있는 모든 부두가 없다 http://msdn.microsoft.com/en-us/library/bb383977.aspx

+0

고마워요,하지만 이것이 내 현재의 솔루션 작동 방식입니다. 내 응용 프로그램이 C# 컴파일러 구현 세부 사항을 알 필요가없는 것을 찾고 있습니다. –

+0

그는 확장 메소드를 사용하여'MethodInfo' 타입에'IsPropertySetAccessor' 메소드를 추가 할 수 있습니다. 그러나 그가 가지고있는 문제점은 그가 가지고있는 것보다 더 나은 메소드로 갈 것입니다. ** "내 프록시가 속성이 구현되는 방법에 대한 친밀한 지식이 있다는 사실을 좋아하지 않습니다 ** ** –

+2

이 대답은 꽤 도움이되지 않습니다 - 질문은"무엇이 * 내부를 결정할 것인가? " 이 " –

5

. 일 수 있으며, 아마도 set_을 제거하고 그 이름의 속성을 찾아 MethodInfo 인스턴스 (invocation.Method)를 속성 접근 자 (GetSetMethod())와 비교해보십시오. 그러나 내가 정직하게 말할 수는 없습니까? 동일한 MethodInfo 인스턴스를 가져 오십시오 (이 동일한 방법 인 경우에도 임).

if(method.IsSpecialName && method.Name.StartsWith("set_")) 
{ 
    var prop = typeof (Foo).GetProperty(method.Name.Substring(4), 
      BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); 
    var accessor = prop.GetSetMethod(); 
    bool isSame = accessor == method; 
} 
-1

첫째, 당신은 그것이 Property 어떤지를 확인 MethodInfo 클래스의 MemberType 속성을 검사 할 수 있습니다.

이제 get 또는 set인지 추측해야합니다. 이름을 분석하지 않으려는 경우 (누군가 "set_Something"메소드의 이름을 지정할 수 있음) 인수를 확인할 수 있습니다. 속성 접근이 하나 개의 값을 반환하고 매개 변수를 선택하지 않는 경우이 설정

  • 입니다 속성 접근이 하나의 매개 변수를 승인하고이 void 반환하는 경우

    • , 이있는 수

    첫 번째 체크에만 관심이있을 수 있습니다

  • +2

    그냥 호기심을 묻습니다. 이 [] 연산자는 어떨까요? 나는 그것이 하나의 매개 변수를 허용한다고 생각한다. – dowhilefor

    +0

    속성 접근 메소드의'MemberType'은'MemberTypes.Property'가 아닌'MemberTypes.Method'입니다. 어쨌든 고마워. –

    +0

    @dowhilefor : 좋은 지적 !!! Reflector/ILDASM에서 결과가 무엇인지 알 수 있습니까? Reflector와이 접근자를 가진 어셈블리는 모두 가지고 있지 않지만 mscorlib.dll은 그것들로 가득 차 있어야합니다. –

    0

    MethodInfo 개체는 01을 얻습니다.속성은 Property type이므로 대신 PropertyInfo으로 캐스팅 할 수 있어야합니다. 이 객체는 이것이 설정 자인지를 알려주는 CanWrite 속성을 노출합니다.

    +0

    음, 문서는'MemberType'이'MethodInfo'를위한'MemberTypes.Method'가 될 것이라고 암시하는 것 같습니다. 사물. –

    +0

    흠, 당신 말이 맞아, 내가 이것을 간과하고 memberTypes.Property에 대한 속성을 만들었습니다, 어쩌면 지금은 더 이상 확실하지 않다는 것을 알고있다 – mtijn

    +0

    'MemberType' 테스트를 실행했습니다. 속성 접근 자 메소드의 'MemberTypes.Method'는'MemberTypes.Property'가 아니므로이 메소드는 작동하지 않습니다. 어쨌든 고마워. –

    3

    잘 모르겠어요 유형의 종류 invocation.Method하지만 PropertyInfo 얻을 수있는 경우 IsSpecialName 사용할 수 있습니다. 불행히도 이것은 속성이 set_ 또는 _get인지뿐만 아니라 오버로드 된 연산자 인지도 알려줍니다.