Sera correctement ce code déterminer si les deux types sont égaux?
Je suis un peu brumeux sur System.Type
contre une véritable type de classe (comme Object
ou XmlDocument
) dans .NET... sera correctement ce code à déterminer si le type d'un objet est égale à une classe-je le préciser?
' Given "myObject" (unknown type), and some class type (let's say "MyClass")...
If myObject.GetType.Equals(MyClass)
If TypeOf(myObject) Is MyClass
If myObject.GetType() Is MyClass
Laquelle est la bonne?
Des points de Bonus si vous pouvez fournir certaines informations sur ce qu'est un identificateur de classe est ce qu'un System.Type
est. 🙂
Remarque: La langue n'a pas d'importance ici, VB.NET ou C# est très bien, le code ci-dessus est pseudocode.
- J'ai toujours pensé que l'objet était techniquement un Type et de toutes les classes ont hérité d'un objet.
Vous devez vous connecter pour publier un commentaire.
Poing, nous allons prendre un regard sur les trois options que vous avez donné:
Ce sera probablement une erreur, puisque les égaux s'attend à un
System.Type
, pas une classe. Une définition de classe n'est pas unSystem.Type
, mais vous pouvez le récupérer en utilisant letypeof
de l'opérateur. Donc, vous pourriez faireinstance.Equals(typeof(MyClass))
, qui allait renvoie true si l'objet est de classe donnée.À l'inverse, vous ne pouvez pas utiliser
typeof
avec les instances, seulement avec des classes, de sorte que le code ci-dessus échoue. Aussi, leis
opérateur vérifie automatiquement la saisie de sorte que vous ne pouvez pas faire untypeof
ou unGetType
lors de son utilisation. Vous devriez aller avecif myObject is MyClass
, qui permettrait de retourner vrai si myObject peut être coulé àMyClass
. C'est différent de dire que c'est une instance de ce type, car il se pourrait que monobjet est une instance d'une classe qui hérite deMyClass
.Encore une fois, la
is
opérateur déjà vérifie le type sur les deux opérandes, de sorte que vous devriez aller avecif myObject is MyClass
.Tout ce que dit, j'aimerais vous expliquer la théorie derrière le système de type. Je ne suis pas spécialiste, donc je vais vous donner un plus explication pratique:
Une définition de la classe label (comme
MyClass
) n'est pas un Système.Type. UnSystem.Type
est une méta-classe qui est générée par le CLR pour représenter le type est défini par votre étiquette. Pour récupérer leSystem.Type
liés à une certaine définition de la classe de l'étiquette, utilisez letypeof
opérateur comme suit:Sur une instance d'objet, vous pouvez récupérer le
System.Type
métadonnées par l'appel de la méthodeGetType()
sur elle. Il vous donnera une instance deSystem.Type
liées à la classe qui représente l'instance réelle. Cela signifie que si votre objet est traité par le compilateur comme une interface ou une classe de base,.GetType()
encore vous donne la la plupart des dérivés de type pour cette instance.Vous pouvez comparer
System.Type
dans le but de vérifier si deux objets sont des instances de la même classe, mais encore une fois, méfiez-vous que votre instance peut être d'un plus type dérivé, L'égalité sera un échec (leSystem.Type
de plus classe dérivée est différente de celle d'un moins un dérivé).Si vous avez besoin de prendre l'héritage de compte, vous pouvez utiliser la méthode
IsAssignableFrom
, comme ceci:C# et VB.Net vous donne deux opérateurs qui permet de faire de ce type de vérification à la volée,
is
etas
.is
n'automatique en tapant la récupération et il est préférable à l'obtention de laSystem.Type
vous-même. Il représente l'héritage:Si vous avez besoin de vérifier le type et convertir l'objet d'utilisation
as
:Ce que vous ne peut pas faire avec
as
est pas correctement le résultat de la vérification; Le problème est que si vous ne cochez pas pour nulles et de l'utiliser, vous obtenez unNullReferenceException
, ce qui permet de masquer le problème correcte (la distribution a échoué). Si vous êtes sûr que vous pouvez faire le casting, puis d'utiliser un cast explicite:Cela permettra de jeter un
InvalidCastException
, de sorte que le code sera plus facile à déboguer.Equals(typeof(MyClass))
ne compile pas et l'assertion similaire surtypeof
pour les classes à la place d'instances est vers l'arrière pour VB. Aussi, leIs
opérateur en VB est différente de celle de C#. En VBIs
effectue de référence des comparaisons, pas le type de vérifications.La
.GetType()
approche pourrait échouer si l'élément est null, alors vous voudrez peut-être un null vérifier d'abord.Je ne sais pas à propos de VB, mais en C# vous utilisez
is
avec le objet, pas de ce genre - c'est à direUne autre différence entre
is
(fait correctement) etGetType()
/Equals
- la différence ici, c'est les sous-classes. Si l'élément est en fait unSuperMyClass
(héritée deMyClass
) puisEquals
ou==
sera de retourfalse
- cependant,is
retournera true.typeof
est limité à une utilisation avec types, pas variables - c'est à diretypeof(MyClass)
, mais pastypeof(obj)
. Si vous souhaitez que le type réel d'un objet dans une variable, utilisezobj.GetType()
.Personnellement, je voudrais utiliser (en C#):
que cela ne constitue un type-vérifier et jeté une fois plutôt que deux
Type
- comment puis-je vérifier si cetteType
est une classe en particulier? Je ne peux pas utiliserIs
avec VB, il crache une erreur.TypeOf
en VB fonctionne avec des variables et non des types. Depuis que cette question a également été marqués VB, l'équivalent de la syntaxe (w/o des retours à la ligne) estDim typed = TryCast(obj, MyClass) If typed IsNot Nothing Then ...
Pour résumer,
is
fera vrai pour la classe et sous-classe.Par exemple:et l'utilisation d'égal à Égal et typeof([Classe]) est équivalent à la classe, à ne pas sous-classe:
if (b.GetType() == typeof(Program)) ;
par hasard?