web-dev-qa-db-fra.com

Quelle est la différence entre System.Type et System.RuntimeType en C #?

J'essayais de faire des tests de convention aujourd'hui, et d'obtenir tous les types dans un assembly (en appelant Assembly.GetTypes()), quand je suis tombé sur quelque chose:

System.RuntimeType:[First.Namespace.FirstClass]

Chaque fois que j'essaie de comparer ce type avec typeof(FirstClass), ils ne sont pas égaux. Ainsi, lorsque j'essaie de trouver tous les types qui contiennent FirstClass comme paramètre générique, je n'en trouve aucun.

Quelle est la différence entre System.RuntimeType Et System.Type?

Existe-t-il un moyen de résoudre mon problème?

76
Edgar Gonzalez

System.RuntimeType Est une classe concrète qui dérive de la classe de base abstraite System.Type. Étant donné que System.RuntimeType N'est pas public, vous en rencontrerez généralement des instances sous le nom System.Type.

Une confusion peut survenir lorsque vous essayez d'obtenir le type d'un objet et que vous appelez par erreur GetType() sur un autre objet représentant le premier type d'objet, plutôt que d'utiliser simplement cet objet directement. Ensuite, Type.ToString() renverra "System.RuntimeType" Lorsque l'objet auquel il est appelé représente un type:

string str = string.Empty;
Type strType = str.GetType();
Type strTypeType = strType.GetType();
strType.ToString();     // returns "System.string"
strTypeType.ToString(); // returns "System.RuntimeType"

Par exemple, dans cet article de blog quelqu'un essaie d'obtenir le type d'une colonne dans une base de données, en faisant quelque chose comme ceci:

object val = reader.GetFieldType(index);
Type runtimeType = val.GetType();
PropertyInfo propInfo = runtimeType.GetProperty("UnderlyingSystemType");
Type type = (Type)propInfo.GetValue(val, null);

Puisque val est déjà un objet Type, val.GetType () renverra un autre objet Type représentant le type System.RuntimeTime Car il s'agit du type concret utilisé pour représenter l'objet type d'origine. Le billet de blog montre ensuite quelques ruses de réflexion inutiles, pour obtenir le type de l'objet de type d'origine, alors que tout ce qui était nécessaire était:

Type type = reader.GetFieldType(index) as Type;

Donc, si votre objet Type signale qu'il représente un System.RuntimeType, Assurez-vous que vous n'avez pas appelé accidentellement GetType() sur un type que vous avez déjà.

94
Ergwun

De la réponse à Différent entre System.Type et System.RuntimeType par Thomas Danecker :

System.Type est une classe de base abstraite. Le CLR a sa mise en œuvre concrète dans le type interne System.RuntimeType. En raison de ce typeof (chaîne) .GetType () renvoie un RuntimeType mais typeof (Type) renvoie un Type normal. L'utilisation de la méthode .Equals fait en fait un object.ReferenceEquals qui retourne false. Pour obtenir les résultats attendus, vous pouvez utiliser type.IsInstanceOfType (élément). Cela retournera également vrai si l'élément est d'un type dérivé. Si vous souhaitez vérifier le type exact, la valeur de retour false de votre méthode est le résultat souhaité. Vous pouvez également utiliser checkType (arrayType, Type.GetType ("System.RuntimeType")) pour vérifier le RuntimeType.

3
John Saunders

En bref...

    "".GetType().ToString()           == "System.String"

    "".GetType().GetType().ToString() == "System.RuntimeType"

La façon dont j'y pense maintenant est que System.Type Est un type de base pour le type qui représente les résultats de la demande de type d'objet au moment de l'exécution, à savoir System.RuntimeType. Ainsi, lorsque vous demandez le type d'un objet, comme dans, "".GetType(), l'instance de System.Type Renvoyée est sa descendante, System.RuntimeType. En fait, il faut s'attendre à ce que la typeof(System.Type).GetType() soit également System.RuntimeType, Mais je pense que le framework empêche spécifiquement cette ... symétrie.

1
George

Jetez un oeil à ce blog, le gars parle de la différence. Il me semble que ces classes sont le résultat de l'optimisation .NET:

http://blogs.msdn.com/b/vancem/archive/2006/10/01/779503.aspx

0
Andrei