Qual é a melhor forma de saber se um método é uma propriedade de dentro da Política de Injeção?

StackOverflow https://stackoverflow.com/questions/73467

Pergunta

Eu tenho um processador personalizado aplicado a uma classe (usando a Diretiva de Injeção de Aplicação Bloco de entlib 4) e eu gostaria de saber se o método de entrada é de propriedade quando Chamar é chamado.É o que meu processador parece.

[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; }
}

Como você pode ver com o meu código de exemplo, a melhor maneira que eu pensei até agora é por analisar o nome do método.Não existe uma maneira melhor de fazer isso?

Foi útil?

Solução

Você também pode verificar IsSpecialName é verdadeiro.isso vai ser verdade em uma propriedade (entre outras coisas)

Do il nível os métodos são expostos da seguinte maneira (utilizando o Ambiente.ExitCode como exemplo):

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

Se você quiser começar a fantasia você poderia verificar depois de extrair o nome que disse propriedade existe, mas para ser honesto

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

bem como inicia-se com get_ ou set_, em seguida, você deve ser bom mesmo para as pessoas que utilizam desagradável nomes (falsificando o hidebysig é bastante fácil, fingir que o IsSpecialName seria muito complicado)

Nada é garantido embora.Alguém poderia emitir uma classe com um set_Foo método que parecia apenas um real definir o método, mas, na verdade, não era um conjunto em uma propriedade somente leitura.A menos que você verifique se a propriedade CanRead/CanWrite bem.

Isso me parece loucura para você que você não está esperando deliberada evasão.Um simples utilitário/extensão do método de MethodInfo que fez esta lógica não seria muito difícil e incluindo IsSpecialName quase que certamente iria cobrir todas as suas necessidades.

Outras dicas

Você pode verificar o IsSpecialName propriedade;ele vai ser true para a propriedade getters e setters.No entanto, também será verdade para outros métodos especiais, como operador de sobrecargas.

Eu não estou familiarizado com esse aplicativo bloco, mas, supondo que MethodBase propriedade é do tipo de Sistema.Reflexão.MethodBase, você poderia dar uma olhada no IsSpecialName propriedade.

Do sistema.Reflexão.MethodBase.IsSpecialName no MSDN

Um casal de você mencionou usando o "IsSpecialName" propriedade do MethodBase tipo.Enquanto é verdade que o irá retornar true para a propriedade de "receber" ou "conjuntos", que também irá retornar true para sobrecargas de operador, tais como add_EventName ou remove_EventName.Portanto, será necessário examinar outros atributos do MethodBase instância para determinar se o seu assessor de propriedade.Infelizmente, se tudo que você tem é uma referência a um MethodBase instância (o que eu acredito é o caso de interceptação de comportamentos na Unidade framework), não existe real de maneira "limpa" para determinar se um setter de propriedade ou getter.A melhor forma que encontrei é da seguinte maneira:

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

É um pouco tarde, mas outras pessoas irão ler este também.Além IsSpecialName e verificar o set_ prefixo (operadores op_, evento subscr./remov.tem add_,remove_) você pode verificar se o método é um jogo para qualquer uma das propriedades de métodos como este:

    bool isProperty = method.ReflectedType.GetProperties().FirstOrDefault(p => 
        p.GetGetMethod().GetHashCode() == method.GetHashCode() 
        || p.GetSetMethod().GetHashCode() == method.GetHashCode())!=null;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top