2009-09-09 13 views
6

Zgodnie z MSDN (sekcja 11.3.6 na C# spec):Sens "tego" dla struct (C#)

wewnątrz konstruktora instancji struktury, this odpowiada parametr out typ struktury i w elemencie funkcji instancji o numerze struct, this odpowiada parametrowi typu struct. W obu przypadkach this jest klasyfikowany jako zmienna i jest możliwa modyfikacja cała struktura w którym element funkcja została wywołana przez przypisanie this lub przepuszczanie this jako parametr ref lub out.

Nie rozumiem. Czym różni się struktura dla danej klasy niż dla klasy? Przykłady kodu są mile widziane

Odpowiedz

11

Eric Lippert miał wspaniałą post na mutowaniu readonly struct po chwili, która naprawdę pomoże ci wyjaśnić problem. Jest nawet przykład kodu i quiz!

Najważniejszym punktem jest to, że struct s są wartością semantyki wartości i class es, więc this musi oznaczać dla nich coś innego. this to readonly dla class, ale nie dla struct. Poniższy kod jest legalne

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

ale jeśli nie jest „struct” zastępuje się wyrazami „class”.

6

Kiedy masz do czynienia ze strukturami, masz do czynienia z typami wartości.

W klasie "this" jest odniesieniem do bieżącej instancji. Pozwala to zmutować instancję klasy przez ustawienie właściwości/pól na klasie.

Jednakże, jeśli jesteś w strukturze, rzeczy działają inaczej. Kiedy używasz metody struct, "to" pozwala ci zmutować strukturę. Jeśli jednak używasz tego w metodzie, prawie zawsze masz do czynienia z kopią "oryginalnej" struktury.

Na przykład:

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

Podczas korzystania z tego:

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 
} 

Teraz część obcy - to jest ważne, a co to cytat mówił:

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

Odpowiedź Jasona i post Erica pokazują jeden aspekt z this, który jest interesujący ... ale jest inny, który jest jeszcze bardziej niepokojący:

Możesz zmienić przypisanie this w ramach metody, nawet jeśli typ jest w przeciwnym razie niezmienny.

Aby zademonstrować go użyjemy struct, który jest przechowywany w nie tylko do odczytu- zmiennej , ale który zawiera pole tylko do odczytu:

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

Poczułem wielką zakłócenia w Mocy, jak jeśli miliony głosów nagle krzyknęły z przerażenia i wzywały do ​​stałej poprawności. Nie pokazuj tego moim współpracownikom w C++. :-) –

+1

Eh, const w C++ to kłamstwo. W języku C++ const często oznacza "obiecuję nie zmieniać tego", a nie "mam gwarancję, że to coś jest niezmienne". –

+0

Przyjemny przykład Jon. W tym przykładzie demonstruje, że struktura może być niezmienna, ale zmienna *, która zawiera strukturę, nie jest. Ta zmienna wciąż może się różnić; dlatego nazywa się zmienną. Jest to szczególnie okropny sposób na różnicowanie. –