Pregunta

¿Qué valor cree con nombre y los parámetros por defecto va a agregar en C # .Net 4.0?

¿Cuál sería un buen uso de estos (que aún no se ha logrado con la sobrecarga y primordial)?

¿Fue útil?

Solución

Puede hacer que los constructores más simple, especialmente para los tipos inmutables (que son importantes para el roscado) - ver aquí para una discusión completa . No es tan bonito como debe ser tal vez, pero mejor que tener un montón de sobrecargas. Es obvio que no se puede utilizar inicializadores de objetos con objetos inmutables, por lo que el habitual:

new Foo {Id = 25, Name = "Fred"}

no está disponible; Me conformo con:

new Foo (Id: 25, Name: "Fred")

Esto se puede extender a la idea general de la simplificación de las sobrecargas, pero en más casos preferiría sobrecargas que se anuncian las combinaciones legales. Los constructores son un poco diferentes, la OMI, ya que son sólo (por lo general) que define el estado inicial.

El lado COM de las cosas también es importante para mucha gente, pero simplemente no usan mucho la interoperabilidad COM -. Por lo que este no es como importante para mí


Los comentarios Editar re; ¿por qué no sólo tiene que utilizar la misma sintaxis que atribuye su uso? Simple - que puede ser ambigua con otros miembros / variables (que no es un problema con atributos); tomar el ejemplo:

[XmlElement("foo", Namespace = "bar")]

que utiliza un parámetro regular (a la ctor, "foo"), y una asignación de llamada. Así que supongamos que usamos para argumentos con nombre regulares:

SomeMethod("foo", SecondArg = "bar");

(que también podría ser un constructor; He usado un método para simplificar)

Ahora ... lo que si tenemos una variable o una propiedad llamada SecondArg? Esto sería ambigua entre el uso de SecondArg como un argumento con nombre de SomeMethod, y asignación de "bar" a SecondArg, y pasando "barra" como un argumento regulares .

Para ilustrar, esto es legal en C # 3.0:

    static void SomeMethod(string x, string y) { }
    static void Main()
    {
        string SecondArg;
        SomeMethod("foo", SecondArg = "bar");
    }

Obviamente, SecondArg podría ser una propiedad, campo, Varialble, etc ...

La sintaxis alternativa no tiene esta ambigüedad.


Editar - esta sección 280Z28: Lo siento por la adición de esto aquí, pero en realidad no es una respuesta única y es demasiado largo para los comentarios e incluye código. Usted insinuado la ambigüedad, pero su ejemplo no destacó el caso de decidir. Creo que el ejemplo que dio señala algo que podría ser confuso, pero el {} requerido alrededor de inicializadores de objeto impide que una ambigüedad sintáctica subyacente. Mi explicación para el siguiente código está incrustado como el comentario de bloque multi-línea.

[AttributeUsage(AttributeTargets.Class)]
public sealed class SomeAttribute : Attribute
{
    public SomeAttribute() { }

    public SomeAttribute(int SomeVariable)
    {
        this.SomeVariable = SomeVariable;
    }

    public int SomeVariable
    {
        get;
        set;
    }
}

/* Here's the true ambiguity: When you add an attribute, and only in this case
 * there would be no way without a new syntax to use named arguments with attributes.
 * This is a particular problem because attributes are a prime candidate for
 * constructor simplification for immutable data types.
 */

// This calls the constructor with 1 arg
[Some(SomeVariable: 3)]
// This calls the constructor with 0 args, followed by setting a property
[Some(SomeVariable = 3)]
public class SomeClass
{
}

Otros consejos

Esto ayudará a esquivar el problema de proporcionar una API decente para trabajar con aplicaciones de oficina! :)

Algunas partes de la API de oficina están bien, pero hay casos extremos que fueron claramente diseñados para el uso de un lenguaje con parámetros opcionales / con nombre. Por eso es que C # tiene que tenerlos.

Parámetros opcionales también evitan el problema donde clases proporcionan docenas de métodos que son simplemente variaciones de los argumentos aceptados.

Tenga en cuenta la clase de excepciones. En lugar de un constructor con argumentos opcionales, tiene cuatro constructores para cada combinación de 'tiene mensaje', y 'tiene excepción interna'. Eso está bien, pero ahora considere lo que sucede si se proporciona un valor nulo a un constructor teniendo una InnerException? ¿Actúa exactamente igual que el constructor sin parámetros InnerException, sortof como el constructor sin parámetros InnerException, o se lanza una excepción de referencia nula?

Un único constructor con 2 parámetros opcionales habría hecho que sea más evidente que pasar un InnerException nula fue equivalente a que no incluyen en absoluto. Un lugar perfecto para los argumentos por defecto.

También no se olvide de que ahora cada clase de excepciones derivadas también tiene que incluir 4 constructores, lo que es una molestia inútil.

Esto hará que interoperabilidad COM mucho más fácil.

Hasta C # 4 VB.Net era un lenguaje mucho mejor para la interoperabilidad. Sin valores por defecto que tiene listas masivas de parámetros ref ficticias en C #.

La brevedad del código es la más obvia que viene a la mente. ¿Por qué definir varias sobrecargas cuando se puede definir una función. También, sin embargo, si tiene dos parámetros de forma idéntica mecanografiadas, no siempre es posible construir el conjunto completo de sobrecargas que pueda necesitar.

También este no se compila:

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
sealed class MyAttribute : Attribute
{
    public MyAttribute(object a = null)
    {

    }
}


class Test
{
    [My] // [My(a: "asd")]
    int prop1 { get; set; }
}

mientras esto hace:

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
sealed class MyAttribute : Attribute
{
    public MyAttribute()
    {

    }

    public object a { get; set; }
}

class Test
{
    [My] // [My(a=null)]
    int prop1 { get; set; }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top