2010-08-12 5 views
7

Quelle est la différence entre une variable déclarée dynamique et une variable déclarée comme System.Object? L'exécution de la fonction suivante semble indiquer que les deux variables se jettent au type correct dynamiquement:Différence entre dynamic et System.Object

void ObjectTest() 
{ 
    System.Object MyTestVar = "test"; 
    dynamic MyTestVar2 = "Testing 123"; 

    Console.WriteLine("{0}", MyTestVar.GetType()); 
    Console.WriteLine("{0}", MyTestVar2.GetType()); 

    MyTestVar = 123; 
    MyTestVar2 = 321; 

    Console.WriteLine("{0}", MyTestVar.GetType()); 
    Console.WriteLine("{0}", MyTestVar2.GetType()); 
} 
+1

J'ai écrit un post à ce sujet il y a quelque temps: http://blogs.msdn.com/b/csharpfaq/archive/2010/01/25/what-is-the-difference-between-dynamic-and-object -keywords.aspx –

Répondre

6

La différence est que MyTestVar2.ToUpper() compile et travaux, sans aucune coulée explicite.

object est un type normal.
dynamic est un type d'espace réservé qui oblige le compilateur à émettre des appels dynamiques à liaison tardive.

GetType() est une fonction normale définie par la classe object qui fonctionne sur l'instance sur laquelle vous l'appelez.
GetType() est complètement non affecté par le type déclaré d'une variable qui fait référence à l'objet sur lequel vous l'appelez. (sauf pour les valeurs nulles)

+0

donc ce que vous dites est que vous pouvez appeler des méthodes spécifiques à l'objet sur les variables dynamiques? – Icemanind

+2

Vous pouvez appeler la méthode _any_ sur les variables 'dynamic'. Le code 'dynamic x = 3; x.Explode(); 'compilera parfaitement bien – SLaks

1

Vous devriez probablement commencer par cet excellent MSDN article. Les différences peuvent se résumer de façon très succincte:

Au moment de la compilation, un élément qui est typé dynamique est supposé soutenir toute opération.

System.Object a seulement une poignée d'opérations qu'il soutient - ToString(), Equals(), etc.

1

La différence fondamentale est compilation (pour objet) vs exécution (pour dynamique) resoulution des appels. Il est également appelé liaison précoce ou tardive. [Note: ajouter une référence à Microsoft.CSharp pour le code suivant pour compiler.]

object o = "Hello world";// fine because a derived type can be assigned to a base type 
    dynamic d= "Hello world";// fine as well 

    Type otype=o.GetType();// compiles because it confirms that object has a GetType() 
    Type dtype=d.GetType();// also compiles but for another reason (i.e.no binding yet) 

    string upperd= d.ToUpper(); // compiles because no binding yet (anything goes :) 
    string uppero= o.ToUpper(); // Fails to compile. Object has no ToUpper() method 

Si vous commentez le dernier appel, l'application devrait fonctionner parce que le CLR, lorsqu'il atteint la dernière seconde d 'appel Au moment de l'exécution, .ToUpper() recherchera une méthode ToUpper() dans le type de chaîne et la trouvera (parce que dans la deuxième instruction d on a assigné une chaîne). Le dernier appel n'a pas été compilé parce que ToUpper() était recherché dans le type System.Object au moment de la compilation, ce qui bien sûr ne sera pas disponible.