2009-09-09 5 views
6

Selon MSDN (section 11.3.6 du C# spec):Signification de "ce" pour une struct (C#)

Au sein d'un constructeur d'instance d'une struct , this correspond à un paramètre out de le type struct, et au sein d'un membre de la fonction instance de une structure, this correspond à un paramètre ref du type struct. Dans les deux cas , this est classée en tant que variable , et il est possible de modifier l'ensemble de la structure pour lequel l'élément de fonction a été appelé par l'attribution à this ou par passage this en tant que paramètre ref ou out.

Je ne comprends pas. Comment est this différent pour une structure que pour une classe? Les exemples de code sont appréciés

Répondre

11

Eric Lippert avait un fabuleux post sur la mutation readonly struct il y a quelque temps qui aidera vraiment à clarifier le problème pour vous. Il y a même un exemple de code, et un quiz! Le point saillant est que s struct s obey sémantique des valeurs et class ne font pas et donc this doit signifier quelque chose de différent pour les deux. this est readonly pour class, mais pas pour struct. Le code suivant est légal

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

mais pas si « struct » est remplacé par « class. »

6

Lorsque vous traitez des structures, vous avez affaire à des types de valeur.

Dans une classe, "this" est une référence à l'instance actuelle. Cela vous permet de faire muter l'instance de classe en définissant les propriétés/champs de la classe. Cependant, si vous êtes dans une structure, les choses agissent différemment. Lorsque vous êtes dans la méthode d'une structure, "this" vous permet de faire muter la structure. Cependant, si vous utilisez ceci dans une méthode, vous avez presque toujours affaire à une copie de la structure "originale".

Par exemple:

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

Lorsque vous utilisez ceci:

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 
} 

Maintenant, la partie étrangère - ceci est valable, et ce que cette citation a dit:

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 réponse de Jason et le post d'Eric montrent un aspect de this qui est intéressant ... mais il y en a un autre qui est encore plus alarmant:

Vous pouvez réaffecter this dans une méthode, même si le type est autrement immuable.

Pour le démontrer, nous allons utiliser un struct qui est stocké dans une variable non readonly, mais qui contient un champ en lecture seule:

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

je me sentais une grande perturbation dans la Force, comme si des millions de voix criaient soudainement de terreur et appelaient à la correction correcte. Merci de ne pas montrer cela à mes collègues C++. :-) –

+1

Eh, const en C++ est un mensonge. En C++, const signifie souvent "je promets de ne pas changer cette chose", et non "j'ai la garantie que cette chose est immuable". –

+0

Bel exemple Jon. Voici ce que vous démontrez, bien que la structure puisse être immuable, la * variable * qui contient la structure ne l'est pas. Cette variable peut encore varier; C'est pourquoi cela s'appelle une variable. C'est juste un moyen particulièrement horrible de le faire varier. –

Questions connexes