Как лучше всего определить, является ли метод свойством внутри внедрения политики? - PullRequest
2 голосов
/ 16 сентября 2008

У меня есть собственный обработчик, примененный к классу (используя блок приложения Policy Injection в 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; }
}

Как вы можете видеть из моего примера кода, лучший способ, о котором я до сих пор думал, - это анализ имени метода. Разве нет лучшего способа сделать это?

Ответы [ 5 ]

4 голосов
/ 16 сентября 2008

Вы также можете проверить, что 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_Foo, который выглядит как метод реального набора, но на самом деле не является набором для свойства только для чтения. Если вы не проверите, является ли свойство CanRead / CanWrite также.

Это кажется мне безумием, хотя вы не ожидаете преднамеренного обхода. Простой метод утилиты / расширения в MethodInfo, который использовал эту логику, не был бы слишком сложным, и включение IsSpecialName почти наверняка охватило бы все ваши потребности.

0 голосов
/ 19 октября 2016

Уже немного поздно, но другие тоже будут это читать. В дополнение к IsSpecialName и проверке префикса set_ (у операторов есть op_, событие subscr./remov. Имеет add_, remove_), вы можете проверить, совпадает ли метод с любым из методов свойств, подобных этому:

    bool isProperty = method.ReflectedType.GetProperties().FirstOrDefault(p => 
        p.GetGetMethod().GetHashCode() == method.GetHashCode() 
        || p.GetSetMethod().GetHashCode() == method.GetHashCode())!=null;
0 голосов
/ 08 июня 2014

Некоторые из вас упомянули использование свойства IsSpecialName типа MethodBase. Несмотря на то, что true вернет true для свойства «gets» или «sets», оно также вернет true для перегрузок операторов, таких как add_EventName или remove_EventName. Поэтому вам нужно будет изучить другие атрибуты экземпляра 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
0 голосов
/ 16 сентября 2008

Я не знаком с этим блоком приложения, но предполагая, что свойство MethodBase имеет тип System.Reflection.MethodBase, вы можете взглянуть на свойство IsSpecialName.

System.Reflection.MethodBase.IsSpecialName на MSDN

0 голосов
/ 16 сентября 2008

Вы можете проверить свойство IsSpecialName; это будет верно для получателей и установщиков свойств. Однако это также будет справедливо для других специальных методов, таких как перегрузки операторов.

...