Estensione ipotetica alla sintassi di inizializzazione della proprietà C #

-1

In C #, quando chiami un costruttore, puoi aggiungere uno o più inizializzatori di proprietà in parentesi graffe:

var foo = new Bar() { Armpit = new Flapdoodle() { Limpet = 2 } };

Che cosa succede se questa funzione è stata generalizzata per "impostare le proprietà su un valore restituito":

var baz = foo.Armpit { Limpet = 4 };

Questo sarebbe utile in casi come questo :

var things = coll
    .Select(x => {
        var a = CreateA(x);
        a.Parent = this;
        return a;
    });

Questo è uno schema comune nella proiezione di collezioni tramite LINQ, ma lo si vede anche altrove: devi dichiarare una variabile locale e aggiungere un po 'di rumore solo per impostare una proprietà su un valore di ritorno prima di passarla a qualcos'altro.

Scrivi

f2(f1());

... ma poi whoops, qualcosa deve cambiare, quindi diventa tre righe:

A a = f1();
a.B = "c";
f2(a);

Sembra che potrebbe essere più bello essere in grado di esprimere lo stesso codice come segue:

var things = coll.Select(x => CreateA(x) { Parent = this } );

f2(f1() { B = "c" });

La mia domanda è questa: è semplicemente non abbastanza utile da curare, o è attivamente una cattiva idea per qualche motivo che è ovvio per il team C # ma non per me?

    
posta Ed Plunkett 07.01.2016 - 17:36
fonte

2 risposte

3

Hai scoperto un vero problema quando vuoi che il tuo codice sia composto da espressioni piuttosto che da istruzioni: non puoi facilmente applicare effetti collaterali a un valore. Tuttavia, l'introduzione della sintassi aggiuntiva è al tempo stesso inelegante e inutile. Invece, preferirei definire una funzione di supporto statico che può essere usata come

f2(With(f1(), a => { a.B = "c"; }));
var things = coll.Select(x => With(CreateA(x), a => { a.Parent = this; }));

dove With sarebbe implementato come With = (x, f) => { f(x); return x; } , cioè la funzione viene valutata solo per i suoi effetti collaterali. Questo modello consente di incorporare effetti collaterali in un'espressione.

    
risposta data 07.01.2016 - 18:11
fonte
0

Is this merely not useful enough to bother with, or is it actively a bad idea for some reason that's obvious to the C# team but not to me?

Non riesco a pensare a nessuna ragione attivamente negativa tranne forse la mancanza di atomicità (che si applica anche alle versioni multi-linea), ma penso che non sia particolarmente utile. Non ho dovuto fare molto di questo, ma poi di nuovo, non mi piacciono i tipi mutabili. Per lo più, trovo che questa sintassi sia per lo più mischiare le sedie a sdraio.

var a = f1();
a.B = "c";
f2(a);

È leggibile quanto

f2(f1() { B = "c" });

per me. Se non altro, la diffusione delle operazioni su più linee aiuta con la leggibilità.

Certo, il caso select è più convincente, ma un select che fa la mutazione mi sembra un po 'puzzolente.

    
risposta data 07.01.2016 - 17:51
fonte

Leggi altre domande sui tag