(Vea a continuación la solución que creé usando la respuesta que acepté)
Estoy tratando de mejorar la capacidad de mantenimiento de algunos códigos que implican reflexión. La aplicación tiene una interfaz .NET Remoting que expone (entre otras cosas) un método llamado Ejecutar para acceder a partes de la aplicación que no están incluidas en su interfaz remota publicada.
Así es como la aplicación designa propiedades (una estática en este ejemplo) a las que se debe acceder mediante Ejecutar:
RemoteMgr.ExposeProperty("SomeSecret", typeof(SomeClass), "SomeProperty");
Entonces un usuario remoto podría llamar:
string response = remoteObject.Execute("SomeSecret");
y la aplicación usaría la reflexión para encontrar SomeClass.SomeProperty y devolver su valor como una cadena.
Desafortunadamente, si alguien cambia el nombre de SomeProperty y olvida cambiar el tercer parámetro de ExposeProperty (), se rompe este mecanismo.
Necesito el equivalente de:
SomeClass.SomeProperty.GetTheNameOfThisPropertyAsAString()
usar como el tercer parm en ExposeProperty para que las herramientas de refactorización se encarguen de los cambios de nombre.
¿Hay alguna forma de hacer esto? Gracias por adelantado.
De acuerdo, esto es lo que terminé creando (según la respuesta que seleccioné y la pregunta a la que hizo referencia):
// <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);
Ahora con esta genial capacidad, es hora de simplificar el método ExposeProperty. Pulir los pomos de las puertas es un trabajo peligroso ...
Gracias a todos.
fuente
Respuestas:
Usando GetMemberInfo desde aquí: Recuperando el nombre de la propiedad de la expresión lambda puede hacer algo como esto:
RemoteMgr.ExposeProperty(() => SomeClass.SomeProperty)
fuente
GetMemberInfo
? No puedo encontrar nada con el paquete de 'utilidades comunes' para Microsoft Enterprise Library, que es lo que MSDN parece indicar que contiene ese método. Hay un paquete "no oficial", pero ser no oficial no es inspirador. La respuesta de JimC , que se basa en esta, es mucho más concisa y no se basa en una biblioteca aparentemente no disponible.Con C # 6.0, esto ya no es un problema, como puede hacer:
Esta expresión se resuelve en tiempo de compilación para
"SomeProperty"
.Documentación de MSDN de nameof .
fuente
const string
! IncreíbleRaiseProperty
en WPF! Utilice RaisePropertyChanged (nameof (propiedad)) en lugar de RaisePropertyChanged ("propiedad")Hay un truco conocido para extraerlo de la expresión lambda (esto es de la clase PropertyObserver, de Josh Smith, en su fundación MVVM):
Lo sentimos, le faltaba algo de contexto. Esto era parte de una clase más grande donde
TPropertySource
está la clase que contiene la propiedad. Puede hacer que la función sea genérica en TPropertySource para extraerla de la clase. Recomiendo echar un vistazo al código completo de la Fundación MVVM .fuente
public static string GetPropertyName<TPropertySource>(Expression<Func<TPropertySource, object>> expression)
luego llamar así:var name = GetPropertyName<TestClass>(x => x.Foo);
De acuerdo, esto es lo que terminé creando (según la respuesta que seleccioné y la pregunta a la que hizo referencia):
Uso:
fuente
La clase PropertyInfo debería ayudarlo a lograr esto, si lo entiendo correctamente.
Método Type.GetProperties ()
¿Esto es lo que necesitas?
fuente
Puede usar Reflection para obtener los nombres reales de las propiedades.
http://www.csharp-examples.net/reflection-property-names/
Si necesita una forma de asignar un "Nombre de cadena" a una propiedad, ¿por qué no escribe un atributo sobre el que pueda reflexionar para obtener el nombre de la cadena?
fuente
Modifiqué tu solución para encadenar múltiples propiedades:
Uso:
fuente
Basado en la respuesta que ya está en la pregunta y en este artículo: https://handcraftsman.wordpress.com/2008/11/11/how-to-get-c-property-names-without-magic-strings/ I Estoy presentando mi solución a este problema:
Y una prueba que también muestra el uso, por ejemplo, y las propiedades estáticas:
fuente
Pregunta anterior, pero otra respuesta a esta pregunta es crear una función estática en una clase auxiliar que use el CallerMemberNameAttribute.
Y luego úsalo como:
fuente
Puede usar la clase StackTrace para obtener el nombre de la función actual (o si coloca el código en una función, luego baje un nivel y obtenga la función de llamada).
Ver http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace(VS.71).aspx
fuente
He estado usando esta respuesta con gran efecto: obtenga la propiedad, como una cadena, de una Expression <Func <TModel, TProperty >>
Me doy cuenta de que ya respondí esta pregunta hace un tiempo. La única ventaja que tiene mi otra respuesta es que funciona para propiedades estáticas. Creo que la sintaxis en esta respuesta es mucho más útil porque no tiene que crear una variable del tipo que desea reflejar.
fuente
Tuve algunas dificultades para usar las soluciones ya sugeridas para mi caso de uso específico, pero finalmente lo descubrí. No creo que mi caso específico sea digno de una nueva pregunta, por lo que estoy publicando mi solución aquí como referencia. (Esto está muy relacionado con la pregunta y proporciona una solución para cualquier otra persona con un caso similar al mío).
El código con el que terminé se ve así:
La parte importante para mí es que en la
CompanyControl
clase el compilador solo me permitirá elegir una propiedad booleana deICompanyViewModel
que facilite que otros desarrolladores lo hagan correctamente.La principal diferencia entre mi solución y la respuesta aceptada es que mi clase es genérica y solo quiero hacer coincidir las propiedades del tipo genérico que son booleanas.
fuente
así es como lo implementé, la razón detrás es si la clase de la que desea obtener el nombre de su miembro no es estática, entonces necesita crear una instancia de eso y luego obtener el nombre del miembro. tan genérico aquí viene a ayudar
el uso es asi
fuente