(Veja abaixo a solução que criei usando a resposta que aceitei)
Estou tentando melhorar a manutenção de algum código que envolve reflexão. O aplicativo possui uma interface .NET Remoting que expõe (entre outras coisas) um método chamado Execute para acessar partes do aplicativo não incluídas em sua interface remota publicada.
Aqui está como o aplicativo designa propriedades (estáticas neste exemplo) que devem ser acessíveis via Execute:
RemoteMgr.ExposeProperty("SomeSecret", typeof(SomeClass), "SomeProperty");
Portanto, um usuário remoto pode ligar para:
string response = remoteObject.Execute("SomeSecret");
e o aplicativo usaria a reflexão para encontrar SomeClass.SomeProperty e retornar seu valor como uma sequência.
Infelizmente, se alguém renomeia SomeProperty e esquece de alterar o terceiro par de ExposeProperty (), ele quebra esse mecanismo.
Eu preciso do equivalente a:
SomeClass.SomeProperty.GetTheNameOfThisPropertyAsAString()
para usar como o terceiro parm em ExposeProperty, para que as ferramentas de refatoração cuidem de renomear.
Existe uma maneira de fazer isso? Desde já, obrigado.
Ok, eis o que acabei criando (com base na resposta que selecionei e na pergunta que ele referenciou):
// <summary>
// Get the name of a static or instance property from a property access lambda.
// </summary>
// <typeparam name="T">Type of the property</typeparam>
// <param name="propertyLambda">lambda expression of the form: '() => Class.Property' or '() => object.Property'</param>
// <returns>The name of the property</returns>
public string GetPropertyName<T>(Expression<Func<T>> propertyLambda)
{
var me = propertyLambda.Body as MemberExpression;
if (me == null)
{
throw new ArgumentException("You must pass a lambda of the form: '() => Class.Property' or '() => object.Property'");
}
return me.Member.Name;
}
Uso:
// Static Property
string name = GetPropertyName(() => SomeClass.SomeProperty);
// Instance Property
string name = GetPropertyName(() => someObject.SomeProperty);
Agora, com esse recurso interessante, é hora de simplificar o método ExposeProperty. Polir maçanetas é um trabalho perigoso ...
Obrigado a todos.
fonte
Respostas:
Usando GetMemberInfo a partir daqui: Recuperando o nome da propriedade da expressão lambda, você pode fazer algo assim:
RemoteMgr.ExposeProperty(() => SomeClass.SomeProperty)
fonte
GetMemberInfo
? Não consigo encontrar nada com o pacote 'utilitários comuns' da Microsoft Enterprise Library, que é o que o MSDN parece indicar contém esse método. Existe um pacote "não oficial", mas não oficial não é inspirador. A resposta de JimC , baseada nesta, é muito mais concisa e não depende de uma biblioteca aparentemente indisponível.Com o C # 6.0, isso agora não é um problema, como você pode fazer:
Essa expressão é resolvida no momento da compilação para
"SomeProperty"
.Documentação do MSDN de nameof .
fonte
const string
! IncrívelRaiseProperty
no WPF! Use RaisePropertyChanged (nameof (propriedade)) em vez de RaisePropertyChanged ( "propriedade")Existe um hack conhecido para extraí-lo da expressão lambda (isto é da classe PropertyObserver, de Josh Smith, em sua fundação MVVM):
Desculpe, faltou algum contexto. Isso fazia parte de uma classe maior, onde
TPropertySource
é a classe que contém a propriedade. Você pode tornar a função genérica em TPropertySource para extraí-la da classe. Eu recomendo dar uma olhada no código completo da MVVM Foundation .fonte
public static string GetPropertyName<TPropertySource>(Expression<Func<TPropertySource, object>> expression)
em seguida, chamar assim:var name = GetPropertyName<TestClass>(x => x.Foo);
Ok, eis o que acabei criando (com base na resposta que selecionei e na pergunta que ele referenciou):
Uso:
fonte
A classe PropertyInfo deve ajudá-lo a conseguir isso, se bem entendi.
Método Type.GetProperties ()
É isto que você precisa?
fonte
Você pode usar o Reflection para obter os nomes reais das propriedades.
http://www.csharp-examples.net/reflection-property-names/
Se você precisa de uma maneira de atribuir um "Nome da string" a uma propriedade, por que não escreve um atributo que possa refletir para obter o nome da string?
fonte
Modifiquei sua solução para encadear várias propriedades:
Uso:
fonte
Com base na resposta que já está na pergunta e neste artigo: https://handcraftsman.wordpress.com/2008/11/11/how-to-get-c-property-names-without-magic-strings/ I estou apresentando minha solução para esse problema:
E um teste que também mostra o uso de propriedades estáticas e de instância:
fonte
Pergunta antiga, mas outra resposta a essa pergunta é criar uma função estática em uma classe auxiliar que usa o CallerMemberNameAttribute.
E então use-o como:
fonte
Você pode usar a classe StackTrace para obter o nome da função atual (ou, se você colocar o código em uma função, desça um nível e obtenha a função de chamada).
Consulte http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace(VS.71).aspx
fonte
Eu tenho usado esta resposta com grande efeito: Obtenha a propriedade, como uma string, de um Expression <Func <TModel, TProperty >>
Sei que já respondi a essa pergunta há um tempo. A única vantagem da minha outra resposta é que ela funciona para propriedades estáticas. Acho a sintaxe nesta resposta muito mais útil, porque você não precisa criar uma variável do tipo que deseja refletir.
fonte
Tive alguma dificuldade em usar as soluções já sugeridas para meu caso de uso específico, mas descobri isso eventualmente. Não acho que meu caso específico seja digno de uma nova pergunta; portanto, estou postando minha solução aqui para referência. (Isso está intimamente relacionado à questão e fornece uma solução para qualquer pessoa com um caso semelhante ao meu).
O código que eu acabei com fica assim:
A parte importante para mim é que, na
CompanyControl
classe, o compilador permitirá apenas escolher uma propriedade booleana deICompanyViewModel
que torna mais fácil para outros desenvolvedores acertar.A principal diferença entre minha solução e a resposta aceita é que minha classe é genérica e só quero corresponder propriedades do tipo genérico que são booleanos.
fonte
é como eu o implementei, a razão por trás disso é que, se a classe que você deseja obter o nome do membro não é estática, é necessário criar uma instância disso e obter o nome do membro. tão genérico aqui vem para ajudar
o uso é assim
fonte