2009-06-25 15 views
22

Quiero conservar una propiedad entre las devoluciones de una aplicación ASP.Net. Actualmente haciendo esto:Obtener el nombre de la propiedad dentro del setter

public int MyIndex 
{ 
    get 
    { 
     return (int)Session[ToString() + "MyIndex"]; 
    } 
} 

pero preferiría algo así como:

public int MyIndex 
{ 
    get 
    { 
     return (int)Session[ToString() + #code_that_returns_property_name#]; 
    } 
} 

Setter omitido, pero simplemente empuja valor en la sesión utilizando la misma cadena. ¿Hay alguna forma de usar la reflexión, o una mejor solución diferente?

+0

Parece que finalmente tenemos algunos [venida dulces sintáctica] (http://blogs.msdn.com/b/csharpfaq/archive/2014/11/20/new-features-in-c-6. aspx) para solucionar esto por nosotros: "A menudo necesitas proporcionar una cadena que nombra algún elemento de programa: cuando lanzas una ArgumentNullException quieres nombrar el argumento culpable, cuando levantas un evento PropertyChanged quieres nombrar la propiedad que cambió, etc. " 'if (x == null) throw new ArgumentNullException (nameof (x));' – JMD

Respuesta

24
public static int Dummy { 
    get { 
     var propertyName = MethodBase.GetCurrentMethod().Name.Substring(4); 
     Console.WriteLine(propertyName); 
     return 0; 
    } 
} 
+1

GetCurrentMethod() devolvió una System.ArgumentException para mí ... –

+0

No, funcionó. No estoy seguro de dónde salió esa excepción. Funciona bien ahora Justo lo que necesitaba. –

+4

Por el amor de Dios, ¡no! ¡El resultado es cinco veces más largo y 100 veces más oscuro que lo que reemplazó! A menos que cambies continuamente de opinión acerca de cómo llamar a esa propiedad, esta es una idea ridícula. (... en mi humilde opinión) –

13

No, no hay una manera simple de hacer lo que quiere hacer. Creo que eres mucho mejor con el código que ya has escrito.

Editar:Esta respuesta ha recibido bastantes votos a favor y entiendo por qué. Si bien es posible hacer lo que el OP quiere hacer, quizás todos deberíamos detenernos y pensar si es o no aconsejable para hacerlo. Parafraseando las palabras inmortales de Dr. Ian Malcom, el hecho de que puedas hacer algo no significa que debas hacerlo.

+0

¿Por qué el voto hacia abajo? es la respuesta más sensata ... :) +1 de mí. –

+1

+1 de mí también, esta es una idea INSANE. Si encuentra que tiene que hacerlo mucho, y el nombre sigue cambiando, entonces administrarlo se convierte en una carga, luego use un archivo .tt para codificar las declaraciones de propiedad o algo así. –

+0

+1 para esto y la respuesta aceptada. Puedo ver por qué el OP querría hacer esto, y el factor atenuante: si la propiedad en cuestión es solo una de 40, hay algo que decir para una sola implementación que está desacoplada de los 40 nombres de propiedades codificadas. El factor atenuante es, por supuesto, si el OP sabe que estas propiedades solo se establecen una vez o un pequeño número de veces, el rendimiento en este nivel es irrelevante. Evitar la optimización prematura. – JMD

7

Puede utilizar MethodInfo.GetCurrentMethod() Nombre de devolver el nombre del método actual:.

public int MyIndex 
{ 
    get 
    { 
     return (int)Session[ToString() + MethodInfo.GetCurrentMethod().Name]; 
    } 
} 

Dado que las propiedades se implementan como métodos bajo el capó, que devolverá un nombre como "get_MyIndex". Si no desea que la parte "get_", puede subcadena a cabo unos pocos caracteres:

public int MyIndex 
{ 
    get 
    { 
     return (int)Session[ToString() + MethodInfo.GetCurrentMethod().Name.Substring(4)]; 
    } 
} 
1

Usted no debe utilizar la propiedad ViewState de su control:

public int MyIndex { 
    get { 
     object index = ViewState["MyIndex"]; 
     return (null == index) ? -1 : (int)index; 
    } 
    set { 
     ViewState["MyIndex"] = value; 
    } 
} 
2

Se puede utilizar una expresión árbol para obtener el nombre de miembro. Es un poco tonto, pero funciona. Aquí está el código.

private string GetPropertyName<TValue>(Expression<Func<BindingSourceType, TValue>> propertySelector) 
{ 
    var memberExpression = propertySelector.Body as MemberExpression; 
    if (memberExpression != null) 
    { 
     return memberExpression.Member.Name; 
    } 
    else 
    { 
     return string.empty;  
    } 
} 

Con ese código se puede hacer lo siguiente

return (int)Session[ToString() + GetPropertyName(MyIndex)]; 

Código robado sin piedad de la respuesta de Romain en el siguiente hilo

+0

¡Qué solución tan elegante! +1 –

+0

No se puede resolver el símbolo 'BindingSourceType' Este es un proyecto de ASP.Net 3.5 ... –

+0

Si lee la respuesta original del otro hilo, dice que BindingSourceType es el nombre de clase que contiene la propiedad. Debe usar el nombre de la clase a la que pertenece la propiedad MyIndex. – adrianbanks

9

Usando CallerMemberName es mucho más rápido y se puede copiar y pegar fácilmente para obtener propiedades adicionales.

private static object GetSessionValue([CallerMemberName]string propertyName = "") 
{ 
    return Session[propertyName]; 
} 

private static void SetSessionValue(object value, [CallerMemberName]string propertyName = "") 
{ 
    Session[propertyName] = value; 
} 

public int MyIndex 
{ 
    get { return (int)GetSessionValue(); } 
    set { SetSessionValue(value); } 
} 
+0

Esta respuesta es la mejor manera de hacerlo ya que funciona en tiempo de compilación y no en tiempo de ejecución. – EvilTak

Cuestiones relacionadas