Versión 6.0 consiguió una nueva característica de nameof, pero no puedo entender el propósito de la misma, ya que sólo se necesita el nombre de la variable y cambia a una cadena en la compilación.

Pensé que podría haber algún propósito al utilizar <T> pero cuando intento nameof(T) solo me imprime una T en lugar de el tipo de uso.

Cualquier idea sobre el propósito?

  • Véase también msdn.microsoft.com/library/dn986596.aspx
  • No había una manera de conseguir que T antes. Hay una manera de obtener el tipo de uso antes.
  • Inicialmente parecía excesivo y todavía no estoy viendo una razón de peso para usar. Tal vez un MVC ejemplo?
  • Sin duda útil cuando refractario/cambio de nombre de la nombre dentro de nameof. También ayuda a prevenir los errores de ortografía.
  • nameof práctico con nunit 3 TestCaseData. Los documentos muestran un método de nombre por la de cadena [Test, TestCaseSource(typeof(MyDataClass), "TestCases")], que puede ser reemplazado con [Test, TestCaseSource(typeof(MyDataClass), nameof(MyDataClass.TestCases))]. Mucho más agradable.
  • La documentación oficial de nameof se ha movido de aquí: docs.microsoft.com/en-us/dotnet/csharp/language-reference/… – también muestra el uso de la llave de los casos que sirven como una muy buena respuesta a la pregunta.
  • Posibles duplicados de ¿Qué es una excepción NullReferenceException, y cómo puedo solucionarlo?

InformationsquelleAutor atikot | 2015-07-29

15 Comentarios

  1. 295

    ¿Qué pasa cuando quieres volver a usar el nombre de una propiedad, por ejemplo, cuando lanzando una excepción basada en un nombre de propiedad, o el manejo de un PropertyChanged evento. Hay numerosos casos donde usted quiere que el nombre de la propiedad.

    Tomar este ejemplo:

    switch (e.PropertyName)
    {
        case nameof(SomeProperty):
        { break; }
    
        //opposed to
        case "SomeOtherProperty":
        { break; }
    }

    En el primer caso, el cambio de nombre de SomeProperty vamos a cambiar el nombre de la propiedad, o se va a romper la compilación. El último caso no.

    Esta es una forma muy útil para mantener tu código de compilación y libre de bugs (especie de).

    (Un muy buen artículo de Eric Lippert por qué infoof no lo hacen, mientras que nameof hizo)

    • Entiendo el punto, sólo añadir que resharper los cambios de las cuerdas cuando la refactorización de nombres, no se si VS tiene una funcionalidad similar.
    • Ha. Pero ambos Resharper y VS no trabajar sobre los proyectos, por ejemplo. Esto hace. De hecho, esta es la mejor solución.
    • Otro caso de uso habitual es de enrutamiento en MVC usando nameof y el nombre de acción en lugar de una rígida cadena.
    • Microsoft proporciona varios ejemplos útiles. msdn.microsoft.com/en-us/library/dn986596.aspx
    • Muy lógico, pero ¿qué acerca del uso nameof en las vistas para el nombre de la acción? Controlador de clase no es estática, por lo que no podemos obtener el nombre de la acción, cualquier solución simple para esto también??
    • No estoy seguro de entender lo que le estás pidiendo. No hay nada que te impida usarlo como public class MyController { public ActionResult Index() { return View(nameof(Index)); } } – y usted puede utilizar nameof en los miembros no estáticos (por ejemplo, usted puede llamar a nameof(MyController.Index) el uso de la clase anterior y se emitirá «Índice»). Echa un vistazo a los ejemplos en msdn.microsoft.com/en-us/library/…
    • wow acceder método no estático nombre sin una instancia?? eso es algo de hardcore compilador lógica lol
    • No veo por qué eso es especial. Los nombres de las variables son siempre los mismos, ¿verdad? Si usted tiene una instancia o no, los nombres de las variables no cambian @sotn
    • Los nombres de las variables, pero tal vez lo que acerca de los nombres de método? Usted puede utilizar nameof con los nombres de método demasiado. Supongamos que tengo una Acción en la aplicación de MVC denominado Índice y quiero cambiar el nombre porque quiero que mis usuarios que acceden al sitio como » /MyController/Home/’ y también no quieren hacerlo mediante el uso de una Ruta de Atributo y solo cambie el nombre a «Casa». La búsqueda para «Índice» y sustituirlo por «Casa» en todo el proyecto puede tomar un montón de tiempo..
    • Y no estoy seguro de entender lo que usted describe. Pero si usted quiere ¿qué es tan especial acerca del uso de nameof en método no estático nombres? Así, en un archivo cshtml por ejemplo; no tenemos acceso a instancia de Controlador y usamos un montón de direcciones url, etc. mediante el uso de UrlHelpers como Url.Action("Index") etc. Por lo tanto, esto significa que podemos utilizar Url.Action(nameof(HomeController.Index)). Y cuando lo cambie en el futuro y gire la vista de compilación, podemos cambiar el nombre de los nombres de acción fácilmente.. hacer Uso de ella sin una instancia es grande imo..
    • No se si entiendes todo esto se hace en tiempo de compilación. No hay instancias en ese tiempo, sin embargo, sólo el código de @sotn
    • lol claro que lo es. nameof no tiene ningún efecto sobre el generado IL etc. Pero, creo que es un buen poco de lo que puede facilitar su trabajo un poco..
    • En caso de que alguien se pregunta qué sucede si SomeProperty obtiene cambiado el nombre de SomeOtherProperty, se obtiene un error de compilación: docs.microsoft.com/en-us/dotnet/csharp/misc/cs0152
    • De hecho, pero no se que error @JohnLBevan

  2. 165

    Es realmente útil para ArgumentException y sus derivados:

    public string DoSomething(string input) 
    {
        if(input == null) 
        {
            throw new ArgumentNullException(nameof(input));
        }
        ...

    Ahora, si alguien refactors el nombre de la input parámetro de la excepción se mantendrá hasta la fecha también.

    También es útil en algunos lugares donde previamente reflexión tuvo que ser utilizado para obtener los nombres de las propiedades o parámetros.

    En su ejemplo nameof(T) obtiene el nombre de un parámetro de tipo – esto puede ser útil también:

    throw new ArgumentException(nameof(T), $"Type {typeof(T)} does not support this method.");

    Otro uso de nameof es para las enumeraciones – por lo general si desea que el nombre de la cadena de una enumeración de utilizar .ToString():

    enum MyEnum { ... FooBar = 7 ... }
    
    Console.WriteLine(MyEnum.FooBar.ToString());
    
    > "FooBar"

    Este hecho, es relativamente lento .Red tiene el valor de enumeración (es decir,7) y encuentra el nombre en tiempo de ejecución.

    Lugar de utilizar nameof:

    Console.WriteLine(nameof(MyEnum.FooBar))
    
    > "FooBar"

    Ahora .Net reemplaza el enum nombre con una cadena en tiempo de compilación.


    Otro uso es para cosas como INotifyPropertyChanged y registro – en ambos casos, usted desea que el nombre del miembro que está llamado a ser pasado 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....");
    }
    • Y le he puesto otra característica interesante de interpolación de cadenas!
    • y typeof(T), que es otro pedazo de tiempo de compilación de azúcar que es útil en circunstancias similares 🙂
    • Una cosa que me falta es algo así como nameofthismethod. Usted puede utilizar Log.Error($"Error in {nameof(DoSomething)}...") pero si copia-pega esto a otros métodos que no se dará cuenta de que es aún refiriéndose a DoSomething. Así, mientras que funciona a la perfección con las variables locales o parámetros el método-el nombre es un problema.
    • ¿Sabe usted si nameOf utilizará el [DisplayName] atributo, si está presente? Para el enum ejemplo yo uso [DisplayName] a menudo con proyectos de MVC
    • no, pero voy a hacer ahora, saludos!
    • ¿Qué averiguaste? También existe la [Description] atributo. Sería bueno dar argumentos a la nameOf, por ejemplo decidir volver el tipo de Nombre cambio de Nombre cuando se utiliza nameOf(System.String)
    • ah, no, yo pensé que usted estaba diciendo que lo hizo. Creo que nameof siempre se pone el nombre real, haciendo caso omiso de los atributos.
    • Por desgracia, un desarrollador tratado de seguir la primera ArgumentException patrón, pero generalizado a todas las excepciones, así que toda mi bloques catch se espolvorean con throw new Exception(nameof(ex)) de la cual se esconde la excepción real y sólo los registros de «ex». La respuesta tiene buenos ejemplos, pero asegúrese de entenderlas antes de intentar aplicarlas.
    • Sí, es bastante especializados y no es algo que se usa a menudo. Sin embargo, de que throw new es un conjunto de otros anti-patrón – me parece sobre-uso de catch ser un problema común con junior devs porque se siente como arreglar el problema (cuando la mayoría de las veces es simplemente ocultarlo).

  3. 25

    Otro caso de uso donde nameof característica de C# 6.0 se vuelve útil – Considerar a la biblioteca como Dapper que hace DB recuperaciones mucho más fácil. Aunque esta es una gran biblioteca, usted necesita para codificar los bienes/los nombres de campo dentro de la consulta. Lo que esto significa es que si usted decide cambiar el nombre de tu propiedad/campo, hay altas posibilidades de que usted se olvide de consulta de actualización para el uso de nuevos nombres de campo. Con la interpolación de cadenas y nameof características, el código se convierte en mucho más fácil de mantener y de typesafe.

    Desde el ejemplo dado en el enlace

    sin nameof

    var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid });

    con nameof

    var dog = connection.Query<Dog>($"select {nameof(Dog.Age)} = @Age, {nameof(Dog.Id)} = @Id", new { Age = (int?)null, Id = guid });
  4. 21

    Su pregunta expresa un propósito. Usted debe ver esto podría ser útil para el registro o lanzar excepciones.

    por ejemplo.

    public void DoStuff(object input)
    {
        if (input == null)
        {
            throw new ArgumentNullException(nameof(input));
        }
    }

    esto es bueno, si puedo cambiar el nombre de la variable el código que se va a romper en su lugar, o devolver una excepción con un mensaje incorrecto.


    Por supuesto, los usos no se limitan a la simple situación. Usted puede utilizar nameof, siempre y cuando pudiera ser útil en el código el nombre de una variable o propiedad.

    Los usos son múltiples, cuando se consideran diferentes de unión y reflexión de las situaciones. Es una excelente manera de traer lo que fueron errores en tiempo de ejecución a tiempo de compilación.

    • para el registro de tan sólo yo pudiera escribir el nombre de la variable a mí mismo, sería más corto
    • Pero entonces, si cambia el nombre de la variable, el compilador no se observe que la cadena no coincide con ninguno más.
    • En realidad yo uso resharper que lleva la cuenta, pero entiendo tu punto de vista.
    • así que yo, pero Resharper sólo genera una advertencia, no un error del compilador. Hay una diferencia entre una certeza y un buen consejo.
    • y, Resharper no comprueba el registro de mensajes
    • Y, sospecho, no comprueba varios otros usos, ya sea – how acerca de WPF enlaces creados en código-detrás, personalizada OnPropertyChanged métodos (que aceptan directamente los nombres de propiedad en lugar de PropertyChangedEventArgs), o llama a la reflexión para buscar un miembro en particular o tipo?

  5. 14

    El más común de los casos de uso que se me ocurre es cuando se trabaja con el INotifyPropertyChanged de la interfaz. (Básicamente todo lo relacionado con WPF y enlaces usa esta interfaz)

    Echa un vistazo a este ejemplo:

    public class Model : INotifyPropertyChanged
    {
        //From the INotifyPropertyChanged interface
        public event PropertyChangedEventHandler PropertyChanged;
    
        private string foo;
        public String Foo
        {
            get { return this.foo; }
            set
            {
                this.foo = value;
                //Old code:
                PropertyChanged(this, new PropertyChangedEventArgs("Foo"));
    
                //New Code:
                PropertyChanged(this, new PropertyChangedEventArgs(nameof(Foo)));           
            }
        }
    }

    Como se puede ver en el antiguo camino que tenemos que pasar una cadena para indicar que la propiedad ha cambiado. Con nameof podemos utilizar el nombre de la propiedad directamente. Esto puede no parecer una gran cosa. Pero la imagen de lo que sucede cuando alguien se cambia el nombre de la propiedad Foo. Cuando se utiliza una cadena de la unión dejará de funcionar, pero el compilador no le avisará. Cuando se utiliza nameof usted obtiene un error de compilador que no hay ninguna propiedad o argumento con el nombre Foo.

    Tenga en cuenta que algunos de los marcos de utilizar alguna reflexión magia para obtener el nombre de la propiedad, pero ahora tenemos nameof esto ya no es necesario.

    • Mientras que este es un enfoque válido, más conveniente (y SECO) enfoque es el uso de la [CallerMemberName] atributo en un nuevo método param para provocar este evento.
    • Estoy de acuerdo CallerMemberName también es bueno, pero su separada de un caso de uso, ya que (como se dijo) sólo se puede utilizar en los métodos. Como para en SECO, no estoy seguro de si [CallerMemberName]string x = null es mejor que nameof(Property). Se podría decir el nombre de la propiedad se usa dos veces, pero eso es básicamente el argumento pasado a la función. No se realmente lo que se quiere decir con SECO creo :).
    • En realidad se puede utilizar en propiedades. Son miembros también. El beneficio de más de nameof es que el establecedor de la propiedad no necesita especificar el nombre de la propiedad a todos, eliminando la posibilidad de copiar/pegar errores.
    • Se trata de un «mejor juntos» situación de INotifyPropertyChanged, el uso de la [CallerMemberNameAttribute] permite la notificación de cambio de limpiamente planteado desde un establecedor de la propiedad, mientras que el nameof sintaxis permite una notificación de cambio de limpiamente planteado desde una ubicación diferente en el código.
  6. 8

    Uso más común será en la validación de entrada, tales como

    //Currently
    void Foo(string par) {
       if (par == null) throw new ArgumentNullException("par");
    }
    
    //C# 6 nameof
    void Foo(string par) {
       if (par == null) throw new ArgumentNullException(nameof(par));
    }

    Que en el primer caso, si refactorizar el método de cambio de par nombre del parámetro, es probable que te olvides de cambio que en el ArgumentNullException. Con nameof usted no tiene que preocuparse por eso.

    Ver también: nameof (C# y Visual Basic Referencia)

  7. 7

    La ASP.NET Núcleo proyecto de MVC utiliza nameof en el AccountController.cs y ManageController.cs con el RedirectToAction método para hacer referencia a una acción en el controlador.

    Ejemplo:

    return RedirectToAction(nameof(HomeController.Index), "Home");

    Esto se traduce en:

    return RedirectToAction("Index", "Home");

    y lleva lleva al usuario a la ‘Índice’ de acción en la «Casa» del controlador, es decir,/Home/Index.

    • ¿Por qué no ir todo de cerdos y el uso return RedirectToAction(nameof(HomeController.Index), nameof(HomeController).Substring(nameof(HomeController),0,nameof(HomeController).Length-"Controller".Length)); ?
    • Oh, chico, es que es feo.
    • porque una de esas cosas que se hace en la compilación y el otro no? 🙂
  8. 6

    Como otros ya han señalado, el nameof operador inserta el nombre que el elemento fue dada en el código fuente.

    Me gustaría añadir que esta es una muy buena idea en términos de refactorización, ya que hace que esta cadena de refactorización seguro. Anteriormente, he utilizado un método estático que utiliza la reflexión para el mismo propósito, pero que tiene un impacto en el rendimiento en tiempo de ejecución. El nameof operador no tiene ningún impacto en el rendimiento en tiempo de ejecución; hace su trabajo en tiempo de compilación. Si usted echa un vistazo a la MSIL código encontrará la cadena incrustada. Consulte el siguiente método y su código desensamblado.

    static void Main(string[] args)
    {
        Console.WriteLine(nameof(args));
        Console.WriteLine("regular text");
    }
    
    //striped nops from the listing
    IL_0001 ldstr args
    IL_0006 call System.Void System.Console::WriteLine(System.String)
    IL_000C ldstr regular text
    IL_0011 call System.Void System.Console::WriteLine(System.String)
    IL_0017 ret

    Sin embargo, que puede ser un inconveniente si va a ofuscar su software. Después de la ofuscación de la cadena incrustada puede no coincidir con el nombre del elemento. Los mecanismos que se basan en este texto se va a romper. Ejemplos de que, incluyendo pero no limitado a: Reflexión, NotifyPropertyChanged …

    Determinar el nombre durante el tiempo de ejecución cuesta un poco el rendimiento, pero es seguro para la ofuscación. Si ofuscación no es ni necesario, ni planeado, me gustaría recomendar el uso de la nameof operador.

  9. 5

    Considerar que el uso de una variable en el código y la necesidad de obtener el nombre de la variable, y digamos de impresión, usted debería tener que usar

    int myVar = 10;
    print("myVar" + " value is " + myVar.toString());

    Y si luego alguien refactors el código y utiliza otro nombre para «mivar», él/ella tendría que ver para la cadena de valor en el código y chenge en consecuencia.

    Lugar si había

    print(nameof(myVar) + " value is " + myVar.toString());

    Sería de gran ayuda para refactorizar automáticamente!

    • Ojalá hubiera sido una variable especial-sintaxis de los parámetros de lo que iba a pasar a un conjunto de tuplas, uno para cada parámetro, que contiene el código fuente de la representación, el Type, y el valor. Que haría posible que el código de invocación de métodos de registro para eliminar una gran cantidad de redundancia.
  10. 4

    El artículo de MSDN listas de MVC de enrutamiento (el ejemplo que me gustó el concepto para mí), entre varios otros. El (formato) descripción párrafo se lee:

    • Al informar de errores en el código,
    • enganchar modelo-vista-controlador (MVC) los enlaces,
    • de disparo de los eventos de cambio de propiedad, etc.,

    a menudo se desea
    capturar el nombre de la cadena de un método. El uso de nameof ayuda mantener su código
    válido cuando el cambio de nombre de las definiciones.

    Antes de que tuviera uso de literales de cadena
    para referirse a las definiciones, que es frágil al cambiar el nombre de elementos de código
    porque las herramientas no sé a que revise estos literales de cadena.

    Los aceptados y valorados de respuestas ya dan excelentes varios ejemplos concretos.

  11. 3

    El propósito de la nameof operador es proporcionar el nombre de la fuente de los artefactos.

    Generalmente el nombre de la fuente es el mismo nombre que los metadatos nombre:

    public void M(string p)
    {
        if (p == null)
        {
            throw new ArgumentNullException(nameof(p));
        }
        ...
    }
    
    public int P
    {
        get
        {
            return p;
        }
        set
        {
            p = value;
            NotifyPropertyChanged(nameof(P));
        }
    }

    Pero esto no siempre puede ser el caso:

    using i = System.Int32;
    ...
    Console.WriteLine(nameof(i)); //prints "i"

    O:

    public static string Extension<T>(this T t)
    {
        return nameof(T); returns "T"
    }

    Un uso le he estado dando a es la nomenclatura de los recursos:

    [Display(
        ResourceType = typeof(Resources),
        Name = nameof(Resources.Title_Name),
        ShortName = nameof(Resources.Title_ShortName),
        Description = nameof(Resources.Title_Description),
        Prompt = nameof(Resources.Title_Prompt))]

    El hecho es que, en este caso, ni siquiera necesitaba el generado propiedades del acceso a los recursos, pero ahora tengo un tiempo de compilación, verificación de que los recursos que existen.

  12. 0

    Uno de los de uso de nameof palabra clave es para la configuración Binding en wpf mediante programación.

    para establecer Binding tiene que establecer Path con una cuerda, y con nameof palabra clave, es posible el uso de Refactorizar opción.

    Por ejemplo, si usted tiene IsEnable propiedad de dependencia en su UserControl y desea enlazar a IsEnable de algunos CheckBox en su UserControl, puede utilizar estos dos códigos:

    CheckBox chk = new CheckBox();
    Binding bnd = new Binding ("IsEnable") { Source = this };
    chk.SetBinding(IsEnabledProperty, bnd);

    y

    CheckBox chk = new CheckBox();
    Binding bnd = new Binding (nameof (IsEnable)) { Source = this };
    chk.SetBinding(IsEnabledProperty, bnd);

    Es obvio que el primer código no puede refactorizar pero la secend uno…

  13. 0

    Anteriormente estábamos usando algo como que:

    //Some form.
    SetFieldReadOnly( () => Entity.UserName );
    ...
    //Base form.
    private void SetFieldReadOnly(Expression<Func<object>> property)
    {
        var propName = GetPropNameFromExpr(property);
        SetFieldsReadOnly(propName);
    }
    
    private void SetFieldReadOnly(string propertyName)
    {
        ...
    }

    Razón – tiempo de compilación de seguridad. Nadie silenciosamente puede cambiar el nombre de la propiedad y romper la lógica de código. Ahora podemos utilizar nameof().

    • Pero nameof también funciona para las variables locales, campos, métodos…
  14. 0

    Tiene ventaja a la hora de utilizar ASP.Net MVC. Cuando se utiliza HTML helper para construir algún tipo de control en vista de que utiliza los nombres de propiedad en nombre de attribure de html de la entrada:

    @Html.TextBoxFor(m => m.CanBeRenamed)

    Hace algo así como que:

    <input type="text" name="CanBeRenamed" />

    Así que ahora, si usted necesita para validar su propiedad en Validar el método, se puede hacer esto:

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
      if (IsNotValid(CanBeRenamed)) {
        yield return new ValidationResult(
          $"Property {nameof(CanBeRenamed)} is not valid",
          new [] { $"{nameof(CanBeRenamed)}" })
      }
    }

    En caso de que si cambia el nombre de la propiedad el uso de herramientas de refactorización, su validación no será quebrantada.

  15. 0

    Otro caso de uso de nameof es la comprobación de la ficha páginas, en lugar de comprobar el índice puede comprobar el Name propiedad de la tabpages como sigue:

    if(tabControl.SelectedTab.Name == nameof(tabSettings))
    {
        //Do something
    }

    Menos desordenado 🙂

Dejar respuesta

Please enter your comment!
Please enter your name here