2010-11-13 5 views
7

In Visual Basic, se avete intenzione di modificare più proprietà di un singolo oggetto, c'è una dichiarazione With/End With:equivalente C# per la parola chiave Visual Basic: "Con" ... "Termina con"?

Dim myObject as Object 

// ' Rather than writing: 
myObject.property1 = something 
myObject.property2 = something2 

// ' You can write: 

with myObject 
    .property1 = something 
    .property2 = something2 
    ... 
End With 

So C# può farlo quando si crea un nuovo oggetto:

Object myObject = new Object { property1 = something, property2 = something2, ...}; 

Ma come posso farlo se myOject è già stato creato (come quello che sta facendo Visual Basic)?

+0

Alcune persone dicono che è male, ma vorrei far notare che le convenzioni di codifica di Microsoft per VB.NET dice che si dovrebbe usare la parola chiave with' 'quando si effettua una serie di chiamate a un oggetto - http://msdn.microsoft.com/en-us/library/h63fsef3.aspx –

risposta

11

Non è possibile farlo in C#.

Questa funzione è specifica per VB e il più vicino possibile in C# è l'inizializzatore dell'oggetto come descritto.

3

se si sta cercando di evitare un sacco di battitura potete dare il vostro oggetto un nome più breve:

var x = myObject; 
x.property1 = something; 
x.property2 = something2; 
+0

Sì, e per fare un passo più in là si può anche fare 'utilizzando (var x = myObject) {/*newline*/x.property1=something;}' – Alxandr

+3

@Alxandr: pessima idea, che chiamerà 'Dispose' alla fine del blocco (e non lo farà anche compilare per i tipi che non implementano 'IDispos able'). –

+0

Oo. Buon punto Colpa mia. Ho solo pensato che smaltito la variabile "x", ma che 'essere un riferimento potrebbe essere fatale :-P – Alxandr

7

ne dici di questo?

static class Extension 
{ 
    public static void With<T>(this T obj, Action<T> a) 
    { 
     a(obj); 
    }  
} 

class Program 
{ 
    class Obj 
    { 
     public int Prop1 { get; set; } 
     public int Prop2 { get; set; } 
     public int Prop3 { get; set; } 
     public int Prop4 { get; set; } 
    } 

    static void Main(string[] args) 
    { 
     var detailedName = new Obj(); 
     detailedName.With(o => { 
      o.Prop1 = 1; 
      o.Prop2 = 2; 
      o.Prop3 = 3; 
      o.Prop4 = 4; 
     }); 
    } 
} 
+0

Crea un metodo di estensione! Quindi puoi fare come 'detailedName.With (o => {o.Prop1 = 4})' – Alxandr

+2

E btw. +1 per la creatività :-) – Alxandr

+0

@Alxandr - Buona idea. – ChaosPandion

3

Perché non C# hanno VB.NET di 'con' operatore?

Molte persone, compresi i progettisti di linguaggio C#, credono che "con" spesso leda la leggibilità e sia più una maledizione che una benedizione. È più chiaro dichiarare una variabile locale con un nome significativo e utilizzare tale variabile per eseguire più operazioni su un singolo oggetto, piuttosto che avere un blocco con una sorta di contesto implicito.

da @Jon Skeet

+6

... e le altre persone credono che VB di "con" l'istruzione è una funzione utile, che offre alcune semantiche che non sono raggiunti da comodamente tramite altri mezzi. – supercat

1

VB.NET include alcuni dei difetti di progettazione di VB6 per motivi di compatibilità. Anche se Javascript ha lo stesso difetto di progettazione (anzi peggio ancora, dato che il suo with porta a costrutti più ambigui), la maggior parte degli altri linguaggi di C-sintassi no, quindi non c'è alcun vantaggio di compatibilità con le versioni precedenti nell'aggiunta a C#.

+0

In realtà c'è un netto vantaggio di avere 'with' in JavaScript. Ti permette di introdurre un nuovo ambito per le tue funzioni! – ChaosPandion

+1

L'istruzione "With" in VB, se utilizzata con le strutture, offre semantica che non è disponibile in modo conveniente in C. Dato che VB "With" utilizza un periodo iniziale per evitare ambiguità, non sono sicuro del motivo per cui lo si considera come un design difetto? – supercat

0

Se l'espressione "con" è un tipo di classe, l'istruzione "With" equivale a creare una nuova variabile temporanea di quel tipo, inizializzata con l'espressione "With" e preceduta da ciascuna ". con quella variabile. Se è un tipo di struttura, tuttavia, le cose sono più complicate. Si consideri il codice (ovviamente non il modo in cui uno normalmente scrivere qualcosa, ma scritto come è quello di fare un punto:.

 
    With MyPoints(N) ' Array of Point 
    N=SomeNewValue 
    .X = MyPoints(N).X 
    .Y = MyPoints(N).Y 
    End With 

La "Con" dichiarazione aggancia in modo efficace un riferimento alla MyPoints (N) Anche se MyPoints è cambiato in qualche altro array, o N è cambiato, il riferimento latch continuerà a puntare allo stesso elemento della stessa matrice che aveva quando è stata eseguita l'istruzione With. Se si dichiarava una variabile locale P di tipo Point and Grabbed MyPoints (N), e quindi scrivere su PX e PY, le scritture colpirebbero solo la copia locale P, invece di aggiornare l'array. Per ottenere una semantica simile in C#, si dovrebbero usare le variabili locali per contenere sia MyPoints che N, oppure posiziona il contenuto dell'istruzione With in una funzione anonima che ha un parametro ref di tipo Point. Per evitare di dover creare una chiusura in fase di esecuzione, la funzione anonima dovrebbe anche accettare, probabilmente per riferimento, eventuali variabili locali di cui avrà bisogno dall'ambito esterno.

0

@Mark Byers answer è buono ma la variabile x si attiverà dopo l'impostazione delle proprietà. E non è possibile utilizzare nuovamente il nome x (nello stesso blocco).

Prova questo (E oggetto deve essere tipo di riferimento in questo esempio):

void Main() 
{ 
    var myObject1 = new Foo(); 
    var myObject2 = new Hoo(); 

    //elided... 

    { 
     var _ = myObject1; 
     _.MyPropertyA = 2; 
     _.MyPropertyB = "3"; 
    } 

    { 
     var _ = myObject2; 
     _.MyPropertyX = 5; 
     _.MyPropertyY = "asd"; 
    } 
}