Определите, является ли экземпляр MethodInfo атрибутом свойства

Я пишу декорирующий прокси с помощью Castle DynamicProxy. Мне нужен прокси-перехватчик для перехвата только записи свойств (не читает), поэтому я проверяю имя метода таким образом:

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

    invocation.Proceed();
}

Теперь это отлично работает, но мне не нравится тот факт, что мой прокси имеет интимное знание о том, как реализуются свойства: я хотел бы заменить проверку имени метода на нечто вроде:

if (invocation.Method.IsPropertySetAccessor)

К сожалению, мой Google-fu не помог мне. Любые идеи?

Ответ 1

Вы можете проверить, существует ли свойство, для которого этот метод является setter (untested):

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

(Вдохновение взято из Marc ответит на соответствующий вопрос.)

Ответ 2

Нет вуду, о котором я знаю. Вы могли бы, возможно, удалить 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;
}

Ответ 3

Я не уверен, какой тип invocation.Method есть, но если вы можете получить PropertyInfo, вы можете использовать IsSpecialName. К сожалению, это говорит не только о том, является ли свойство set_ или _get, но также является перегруженным оператором.

Ответ 4

из MethodInfo получить MemberType, который должен сказать, что это Тип свойства, чтобы вы могли его отличить до PropertyInfo. этот объект предоставляет свойство CanWrite, которое указывает, является ли это установщиком.

Ответ 5

Сначала вы можете изучить свойство MemberType класса MethodInfo, чтобы увидеть, есть ли он Property.

Теперь вы должны попытаться угадать, есть ли это get или set. Если вы не хотите анализировать имя (кто-то может назвать метод "set_Something" ), вы можете проверить аргументы.

  • Если свойство accessor принимает один параметр и возвращает void, это набор
  • Если свойство accessor возвращает одно значение и не выбирает параметры, это get

Вас может заинтересовать только первая проверка