Как лучше всего определить, является ли метод свойством в рамках внедрения политики?

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
2 274
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

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

System.Reflection.MethodBase.IsSpecialName в MSDN

Ответ принят как подходящий

Вы также можете проверить, что IsSpecialName истинно. это будет верно для свойства (среди прочего)

На уровне 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 почти наверняка покроет все ваши потребности.

Остерегайтесь: условие if также истинно для методов, которые добавляют или удаляют обработчики событий.

Mr.Yeah 29.03.2019 20:50

Некоторые из вас упомянули об использовании свойства IsSpecialName типа MethodBase. Хотя верно, что функция вернет истину для свойства «получает» или «устанавливает», она также вернет истину для перегрузок операторов, таких как 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

Немного поздно, но другие люди тоже это прочтут. В дополнение к 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;

Другие вопросы по теме