La versión 6.0 tiene una nueva característica de nameof , pero no puedo entender su propósito, ya que solo toma el nombre de la variable y lo cambia a una cadena en la compilación.
Pensé que podría tener algún propósito al usar <T> pero cuando trato de nameof(T) simplemente me imprime una T en lugar del tipo usado.
¿Alguna idea sobre el propósito?
¿Qué pasa con los casos en los que desea reutilizar el nombre de una propiedad, por ejemplo, al generar una excepción basada en el nombre de una propiedad o al manejar un evento PropertyChanged ? Hay numerosos casos en los que le gustaría tener el nombre de la propiedad.
Toma este ejemplo:
switch (e.PropertyName) { case nameof(SomeProperty): { break; } // opposed to case "SomeOtherProperty": { break; } } En el primer caso, cambiar el nombre de SomeProperty provocará un error de compilación si no cambia tanto la definición de la propiedad como la nameof(SomeProperty) . En el segundo caso, cambiar el nombre de SomeOtherProperty o alterar la cadena "SomeOtherProperty" dará como resultado un comportamiento de tiempo de ejecución interrumpido silenciosamente, sin errores ni advertencias en el momento de la compilación.
Esta es una forma muy útil de mantener su código compilado y libre de errores (más o menos).
(Un muy buen artículo de Eric Lippert por qué infoof no lo logró, mientras que nameof sí)
Es realmente útil para ArgumentException y sus derivados:
public string DoSomething(string input) { if(input == null) { throw new ArgumentNullException(nameof(input)); } ... Ahora, si alguien refactoriza el nombre del parámetro de input , la excepción también se mantendrá actualizada.
También es útil en algunos lugares donde antes se tenía que usar la reflexión para obtener los nombres de propiedades o parámetros.
En su ejemplo nameof(T) obtiene el nombre del parámetro de tipo; esto también puede ser útil:
throw new ArgumentException(nameof(T), $"Type {typeof(T)} does not support this method."); Otro uso de nameof es para enumeraciones; por lo general, si desea el nombre de cadena de una enumeración, use .ToString() :
enum MyEnum { ... FooBar = 7 ... } Console.WriteLine(MyEnum.FooBar.ToString()); > "FooBar" En realidad, esto es relativamente lento ya que .Net contiene el valor de enumeración (es decir, 7 ) y encuentra el nombre en tiempo de ejecución.
En su lugar, use nameof :
Console.WriteLine(nameof(MyEnum.FooBar)) > "FooBar"Ahora .Net reemplaza el nombre de enumeración con una cadena en tiempo de compilación.
Otro uso más es para cosas como INotifyPropertyChanged y registro; en ambos casos, desea que el nombre del miembro al que está llamando se pase a otro método:
// Property with notify of change public int Foo { get { return this.foo; } set { this.foo = value; PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.Foo)); } }O...
// Write a log, audit or trace for the method called void DoSomething(... params ...) { Log(nameof(DoSomething), "Message...."); }Otro caso de uso en el que la función nameof de C# 6.0 se vuelve útil : considere una biblioteca comoDapper que facilita mucho las recuperaciones de bases de datos. Si bien esta es una gran biblioteca, debe codificar los nombres de propiedades/campos dentro de la consulta. Lo que esto significa es que si decide cambiar el nombre de su propiedad/campo, hay muchas posibilidades de que olvide actualizar la consulta para usar nuevos nombres de campo. Con la interpolación de cadenas y las funciones nameof , el código se vuelve mucho más fácil de mantener y escribir con seguridad.
Del ejemplo dado en el enlace
sin nombre de
var dog = connection.Query<Dog>( "select Age = @Age, Id = @Id", new {Age = (int?) null, Id = guid});con nombre de
var dog = connection.Query<Dog>( $"select {nameof(Dog.Age)} = @Age, {nameof(Dog.Id)} = @Id", new {Age = (int?) null, Id = guid});