2009-10-11 6 views
1

est C# Object/object une valeur de type ou le type de référence?C# objet/objet

J'ai examiné qu'ils peuvent garder les références, mais cette référence ne peut pas être utilisé pour changer les objets.

using System; 

class MyClass 
{ 
    public static void Swap(Object obj1, Object obj2) 
    { 
     Console.WriteLine("After Swapping"); 
     obj1 = 100; 
     obj2 = 200; 
    } 
} 

class MainClass 
{ 
    static void Main(string[] args) 
    { 
     Object obj1 = new Object(); 
     obj1 = 10; 

     Object obj2 = new Object(); 
     obj2 = 20; 

     Console.WriteLine(obj1.ToString()); 
     Console.WriteLine(obj2.ToString()); 

     MyClass.Swap(obj1, obj2); 

     Console.WriteLine(obj1.ToString()); 
     Console.WriteLine(obj2.ToString()); 

     Console.ReadLine(); 
    } 
} 
+0

Veuillez poster un code qui démontre que vous ne pouvez pas modifier les références d'objet. – Kobi

Répondre

5

Les modifications apportées à Swap sont limités à là - vous ne jouez avec des pointeurs (et la boxe), les références en dehors de la fonction restent les mêmes (vous avez 4 références). Vous verrez la différence si vous avez changé la signature de votre méthode:

essayer Swap(ref Object obj1, ref Object obj2).

va de même pour

Object obj1 = new Object(); 
obj1 = 10; 

Ce n'est pas mieux que Object obj1 = 10;, par la façon dont

Pour voir l'objet est vraiment un type de références, utilisez une classe avec des propriétés, par exemple:

class Foo { 
    public int Value {get; set;} 
} 

Modifiez le Value de l'objet dans Swap, et vous verrez les effets sur votre programme principal.

4

Il est un type de référence - si vous regardez le documentation, vous verrez qu'il est déclaré en tant que classe. Toutes les classes sont des types de référence.

Et oui, la même chose est vraie pour System.ValueType et System.Enum - ce sont les deux types de référence, malgré les noms ... les types de valeur en dérivent cependant.

EDIT: Votre mise à jour montre que ce que vous êtes vraiment confus par le passage de paramètres est. Voir mes articles sur parameter passing in C# et reference/value types.

+0

plz voir la mise à jour. – anonymous

+0

Je n'ai jamais su que System.ValueType était lui-même un type de référence ... J'ai toujours supposé que c'était un type de valeur. On dirait qu'il a été fait un type de référence afin que Equals() et GetHashCode() puissent être substitués pour comparer le contenu. – overstood

+1

C'est plus qu'un type de valeur lui-même, rien ne pourrait en dériver ... –

0

comme object est mère de tous les objets est un type de référence

0

Votre devrait écrire du code comme ceci:

using System; 

class MyClass 
{ 
    public static void Swap(ref Object obj1, ref Object obj2) // Use keyword 'ref' 
    { 
     Console.WriteLine("After Swapping"); 
     obj1 = 100; 
     obj2 = 200; 
    } 
} 

class MainClass 
{ 
    static void Main(string[] args) 
    { 
     Object obj1 = new Object(); 
     obj1 = 10; 

     Object obj2 = new Object(); 
     obj2 = 20; 

     Console.WriteLine(obj1.ToString()); 
     Console.WriteLine(obj2.ToString()); 

     MyClass.Swap(ref obj1, ref obj2); // Use keyword 'ref' 

     Console.WriteLine(obj1.ToString()); 
     Console.WriteLine(obj2.ToString()); 

     Console.ReadLine(); 
    } 
} 

Vous pouvez lire plus d'informations sur mot-clé 'ref' dans MSDN

Citation de MSDN:

Paramètres Passing (programmation C# Guide)

En C#, les paramètres peuvent être transmis soit par valeur ou par référence. Le passage de paramètres par référence permet membres de fonction, méthodes, propriétés, indexeurs, opérateurs et constructeurs pour modifier la valeur des paramètres et de laisser cette modification persister. Pour transmettre un paramètre par référence, utilisez le mot-clé réf ou out. Par souci de simplicité, seul le mot-clé ref est utilisé dans les exemples dans cette rubrique.Pour plus d'informations sur la différence entre ref et out, voir ref (C# Reference), out (référence C#) et Passing Arrays à l'aide de ref et out (C# Guide de programmation). Par exemple:

// Passing by value 
static void Square(int x) 
{ 
    // code... 
} 
// Passing by reference 
static void Square(ref int x) 
{ 
    // code... 
} 

(c) MSDN - Passing Parameters (C# Programming Guide)

0

C'est parce que le type d'exécution de obj1 et obj2 est System.Int32 (vérifier avec obj1.GetType().ToString()), qui est un type de valeur. Aucune copie de référence n'est faite dans votre fonction d'échange. Au lieu de cela, il effectue uniquement des opérations de boxe et de déballage, qui n'ont aucun effet sur les variables réelles.

+0

Cela ne fonctionnerait pas non plus pour les types de référence, pas seulement pour 'int' - faire' obj1 = new Foo(); 'change la référence localement sur la fonction. – Kobi

2

S'il vous plaît noter que

Object obj1 = new Object(); 
obj1 = 10; 

est le même que:

Object obj1 = 10; 

Parce que le compilateur intervient avec 'la boxe' pour transformer la valeur de type int dans un type de référence. Et à l'intérieur de votre méthode d'échange, vous êtes de nouveau en train de boxer, écrasant les paramètres de référence.

So Kobi et la solution de Dreamwalker, en utilisant des paramètres ref, marche réellement:

public static void Swap(ref Object obj1, ref Object obj2) // Use keyword 'ref' 

Mais il est loin d'être idéale.

Une meilleure solution serait une méthode générique:

static void Swap<T>(ref T x, ref T y) 
{ 
    T z = x; x = y; y = z; 
} 

Ainsi, le compilateur peut générer le code le plus approprié pour référence- et types de valeur.

+0

Depuis quand est-ce que 10 = 100? – RCIX