Domanda

Che valore pensi che denominate e di parametri di default aggiungerà in C # .Net 4.0?

Che cosa sarebbe un buon uso per questi (che non sia già stato raggiunto con il sovraccarico e prioritario)?

È stato utile?

Soluzione

Si può fare costruttori più semplice, soprattutto per i tipi immutabili (che sono importanti per la filettatura) - vedi qui per una discussione pieno. Non è così bello come dovrebbe essere forse, ma più bello di avere un sacco di sovraccarichi. È, ovviamente, non è possibile utilizzare inizializzatori di oggetti con oggetti immutabili, quindi il solito:

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

non è disponibile; Mi accontento di:

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

Questo può essere esteso per l'idea generale di sovraccarichi semplificando, ma in più casi preferirei sovraccarichi che pubblicizzano le combinazioni di legge. I costruttori sono un po 'diverso, IMO, dal momento che si sono solo (in genere) che definisce lo stato iniziale.

Il lato COM delle cose è importante anche per un sacco di gente, ma io semplicemente non usano molto l'interoperabilità COM -. Quindi questo non è come importante per me


Commenti Modifica re; perché non hanno solo utilizzano la stessa sintassi che attribuisce l'uso? Semplice - può essere ambiguo con altri utenti / variabili (che non è un problema con gli attributi); prendere l'esempio:

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

che utilizza un parametro regolare (al ctor, "foo"), e uno di nome assegnazione. Quindi supponiamo che usiamo questo per regolari argomenti con nome:

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

(che potrebbe anche essere un costruttore, ho usato un metodo per semplicità)

Ora ... che cosa se abbiamo una variabile o una proprietà chiamata SecondArg? Questo sarebbe ambiguo tra l'utilizzo SecondArg come argomento di nome per SomeMethod, e l'assegnazione di "bar" per SecondArg, e passando "bar" come argomento regolare .

Per illustrare, questo è legale in C # 3.0:

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

Ovviamente, SecondArg potrebbe essere una proprietà, campo, varialble, ecc ...

La sintassi alternativa non ha questa ambiguità.


Modifica - questa sezione 280Z28: Ci scusiamo per l'aggiunta di questo qui, ma non è davvero una risposta unica ed è troppo lungo per i commenti e include il codice. Si è accennato alla ambiguità, ma il tuo esempio non ha evidenziato il caso di decidere. Credo che l'esempio che ha dato sottolinea qualcosa che potrebbe essere fonte di confusione, ma la richiesta {} intorno inizializzatori oggetto impedisce l'un'ambiguità sintattica sottostante. La mia spiegazione per il seguente codice è incorporato come il blocco di commento su più righe.

[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
{
}

Altri suggerimenti

Esso contribuirà a schivare il problema di fornire un API decente per lavorare con le applicazioni di Office! :)

Alcune parti della API dell'Ufficio vanno bene, ma ci sono casi limite che sono stati chiaramente progettati per l'utilizzo da una lingua con parametri facoltativi / named. Ecco perché C # deve averli.

I parametri facoltativi anche evitano il problema in cui classi forniscono decine di metodi che sono solo variazioni su argomenti accettate.

Si consideri la classe Exception. Invece di un costruttore con argomenti opzionali, ha quattro costruttori per ogni combinazione di 'presenta messaggio', e 'dotato l'eccezione interna'. Questo è bene, ma ora consideriamo cosa succede se si fornisce un valore nullo per un costruttore di prendere un innerException? Ha agire esattamente come il costruttore con con nessun parametro innerException, sortof come il costruttore senza parametri innerException, o lo fa un'eccezione riferimento null?

Un singolo costruttore con 2 parametri facoltativi avrebbe reso più evidente che passa un innerException nullo era pari a non comprese affatto. Un luogo perfetto per gli argomenti di default.

Inoltre, non dimenticare che ormai ogni classe Exception derivata deve anche includere 4 costruttori, che è una seccatura inutile.

Si farà interoperabilità COM molto più facile.

Fino a C # 4 VB.Net era una lingua molto meglio per l'interoperabilità. Senza di default si hanno enormi liste di parametri ref fittizi in C #.

La brevità del codice è la più ovvia che viene in mente. Perché definire diversi overload quando è possibile definire una funzione. Inoltre, anche se, se si dispone di due parametri in modo identico digitati, non è sempre possibile costruire il set completo di sovraccarichi si potrebbe aver bisogno.

Anche questo non può essere compilato:

[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; }
}

mentre questo fa:

[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; }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top