Domanda

In Visual Basic, se avete intenzione di modificare più proprietà di un singolo oggetto, c'è una dichiarazione With/End With:

Dim myObject as Object

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

// ' You can write:

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

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

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

Ma come faccio a fare che, se è già stato creato myOject (come quello che sta facendo Visual Basic)?

È stato utile?

Soluzione

Non si può fare questo in C #.

Questa funzione è specifica per VB e il più vicino si può venire in C # è l'inizializzazione degli oggetti, come si descrive.

Altri suggerimenti

Che 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;
        });
    }
}

Se stai 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;
  

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

     

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

     

@ Jon Skeet

VB.NET include alcuni dei difetti di progettazione di VB6 per il bene di compatibilità all'indietro. Mentre Javascript ha lo stesso difetto di progettazione (anzi un ancora peggiore, come i suoi cavi with di costrutti più ambiguo), più altri linguaggi C-sintassi non lo fanno, quindi non c'è alcun beneficio indietro-compatibilità in aggiunta a C #.

@ Mark Byers risposta è buona, ma il x variabile vivrà dopo la proprietà sono impostate. E non si può utilizzare di nuovo nome x (in stesso blocco).

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

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

    //elided...

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

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

Se il "con" espressione è un tipo di classe, il "con" dichiarazione equivale a creare una nuova variabile temporanea di quel tipo, inizializzato al "con" l'espressione, e che precede ogni leader "" con tale variabile. Se si tratta di un tipo di struttura, però, le cose sono più complicate. Si consideri il codice (ovviamente non il modo in cui si farebbe qualcosa di normalmente di scrittura, 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

Il "Con" dichiarazione aggancia in modo efficace un riferimento alla MyPoints (N). Anche se MyPoints viene modificato in un altro array o N viene modificato, il riferimento latched punterà ancora allo stesso elemento dello stesso array come quando dell'istruzione Con è stato eseguito. Se uno ha dichiarato una variabile P locale di tipo Point e MyPoints afferrato (N), e poi scrivere a P.X e P.Y, le scritture avrebbero colpito solo la copia locale P, invece di aggiornare la matrice. Per ottenere la semantica simili in C #, si dovrebbe sia per uso variabili locali per contenere sia MyPoints e N, o altro posto il contenuto della dichiarazione con all'interno 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 con riferimento, tutte le variabili locali che avrà bisogno dall'ambito di applicazione esterna.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top