2009-09-09 17 views
6

Secondo MSDN (Sezione 11.3.6 del C# spec):significato di "questo" per una struct (C#)

all'interno di un'istanza di costruzione di una struct, this corrisponde ad un out parametro il tipo struct e all'interno di una funzione di istanza membro di una struttura, this corrisponde a un parametro ref del tipo di struttura. In entrambi i casi , this è classificato come variabile , ed è possibile modificare tutta struct per cui l'organo funzione è stata richiamata da assegnando this o passando this come parametro ref o out.

Non capisco. In che modo this è diverso per una struttura rispetto a una classe? Esempi di codice sono apprezzati

risposta

11

Eric Lippert ha avuto un favoloso post in mutazione readonly struct un po 'indietro che aiuterà davvero a chiarire il problema per voi. C'è anche un esempio di codice e un quiz!

Il punto saliente è che la semantica dei valori obbedii struct s e class e così via this devono significare qualcosa di diverso per i due. this è readonly per un class, ma non per un struct. Il seguente codice è legale

struct Point { 
    public int x; 
    public int y; 

    public Point(int x, int y) { 
     this.x = x; 
     this.y = y; 
    } 

    public void DoGoTime() { 
     GoTime(ref this); 
    } 

    public static void GoTime(ref Point p) { 
     p.x = 100; 
     p.y = 100; 
    } 
} 

ma non è se "struct" è sostituito da "class."

6

Quando hai a che fare con le strutture, hai a che fare con i tipi di valore.

In una classe, "questo" è un riferimento all'istanza corrente. Ciò consente di mutare l'istanza della classe impostando proprietà/campi sulla classe.

Tuttavia, se ci si trova in una struttura, le cose si comportano in modo diverso. Quando sei nel metodo di una struct, "this" ti permette di mutare la struttura. Tuttavia, se stai usando questo metodo, hai quasi sempre a che fare con una copia della struttura "originale".

Ad esempio:

struct Test 
{ 
    int i; 
    void Mutate() { 
     this.i += 1; 
    } 
} 

Quando si utilizza questa:

void MutateTest(Test instance) 
{ 
    instance.Mutate(); 
} 

{ 
    Test test = new Test(); 
    test.i = 3; 
    Console.WriteLine(test.i); // Writes 3 
    test.Mutate(); // test.i is now 4 
    Console.WriteLine(test.i); // Writes 4 
    MutateTest(test); // MutateTest works on a copy.. "this" is only part of the copy itself 
    Console.WriteLine(test.i); // Writes 4 still 
} 

Ora, la parte sconosciuto - questo è valido, e ciò che quella citazione stava dicendo:

struct Test 
{ 
    public Test(int value) 
    { 
     this.i = value; 
    } 
    int i; 

    void Mutate(int newValue) { 
     this = new Test(newValue); // This wouldn't work with classes 
    } 
} 


/// 
{ 
    Test test = new Test(); 
    test.i = 3; 
    Console.WriteLine(test.i); // Writes 3 
    test.Mutate(4); 
    Console.WriteLine(test.i); // Writes 4 
6

La risposta di Jason e il post di Eric mostrano un aspetto di this che è interessante ... ma ce n'è un altro che è ancora più allarmante:

È possibile riassegnare this all'interno di un metodo, anche se il tipo è altrimenti immutabile.

Per dimostrarlo, useremo una struttura che è memorizzato in un non-sola lettura variabile , ma che contiene un campo di sola lettura:

using System; 

public struct LooksImmutable 
{ 
    private readonly int value; 
    public int Value { get { return value; } } 

    public LooksImmutable(int value) 
    { 
     this.value = value; 
    } 

    public void GoCrazy() 
    { 
     this = new LooksImmutable(value + 1); 
    } 
} 

public class Test 
{ 
    static void Main() 
    { 
     LooksImmutable x = new LooksImmutable(5); 
     Console.WriteLine(x.Value); 
     x.GoCrazy(); 
     Console.WriteLine(x.Value); 
    } 
} 
+0

ho sentito una grande interferenza nella Forza, come se milioni di voci improvvisamente gridavano nel terrore e chiedevano la correttezza costante. Per favore non mostrare questo ai miei colleghi C++. :-) –

+1

Eh, const in C++ è una bugia. In C++, const significa spesso "Prometto di non cambiare questa cosa", e non "Ho la garanzia che questa cosa sia immutabile". –

+0

Bel esempio Jon. Qui quello che stai dimostrando è che sebbene la struttura possa essere immutabile, la * variabile * che contiene la struttura non lo è. Quella variabile può ancora variare; è per questo che ha chiamato una variabile. Questo è solo un modo particolarmente orribile per farlo variare. –

Problemi correlati