该代码能否正确确定两种类型是否相等?
我对 System.Type
与 .NET 中的实际类类型(如 Object
或 XmlDocument
)有点模糊……这会吗?代码正确确定特定对象的类型是否等于我指定的类?
' 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
哪一个是正确的?
如果您可以提供一些有关什么是类标识符以及什么是 System.Type 的信息,那就加分了。 :)
注意:这里的语言并不重要,VB.NET 或 C# 都可以,上面的代码是伪代码。
I'm a little foggy on System.Type
versus an actual class type (like Object
or XmlDocument
) in .NET... will this code correctly determine if the type of a particular object is equal to a class I specify?
' 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
Which one is correct?
Bonus points if you can provide some information on what a class identifier is versus what a System.Type
is. :)
Note: The language doesn't matter here, VB.NET or C# is fine, the code above is pseudocode.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
首先让我们看一下您提供的三个选项:
这可能会导致错误,因为 equals 需要一个
System.Type
,而不是一个类。类定义不是System.Type
,但您可以使用typeof
运算符检索它。因此,您可以执行instance.Equals(typeof(MyClass))
,如果对象属于给定类,它将返回 true。相反,您不能将
typeof
与实例一起使用,只能与类一起使用,因此上述代码将失败。此外,is
运算符会自动检查输入,因此您在使用它时无法执行typeof
或GetType
操作。您应该选择if myObject is MyClass
,如果myObject 可以转换为MyClass
,则返回 true。这与说它是该类型的实例不同,因为 myObject 可能是继承自MyClass
的类的实例。同样,
is
运算符已经检查了两个操作数的类型,因此您应该使用if myObject is MyClass
。综上所述,我想解释一下类型系统背后的“理论”。我不是专家,所以我给你一个更实际的解释:
类定义标签(如
MyClass
)不是System.Type。System.Type
是由 CLR 生成的元数据类,用于表示标签定义的类型。要检索与某个类定义标签相关的System.Type
,请使用typeof
运算符,如下所示:在对象实例上,您可以检索
通过调用方法
元数据。它将为您提供一个与代表实际实例的类相关的GetType()
来获取 System.TypeSystem.Type
实例。这意味着,如果编译器将您的对象视为接口或基类,.GetType()
仍会为您提供该实例的最派生类型。< /p>System.Type
与派生程度较低的类的不同)。如果需要考虑继承,可以使用方法
IsAssignableFrom
,如下所示:C# 和 VB.Net 为您提供了两个运算符,使您能够即时进行类型检查,
是
和as
。is
会自动进行类型检索,并且优于您自己获取System.Type
。它也解释了继承:如果您需要检查类型并转换对象,请使用
as
:您不能使用
as
做的是不执行正确的结果检查;问题是,如果您不检查它是否为 null 并使用它,您会得到一个 NullReferenceException,这将隐藏正确的问题(强制转换失败)。如果您确定可以进行强制转换,请使用显式强制转换:这将引发
InvalidCastException
,因此代码将更容易调试。Fist let's take a look on the three options you gave:
This will probably result in a error, since the equals expects a
System.Type
, not a class. A class definition is not aSystem.Type
, but you can retrieve it using thetypeof
operator. So you could doinstance.Equals(typeof(MyClass))
, which would return true if the object is of the given class.Conversely, you can't use
typeof
with instances, only with classes, so the above code would fail. Also, theis
operator automatically checks the typing so you can't do atypeof
or aGetType
when using it. You should go withif myObject is MyClass
, which would return true if myObject can be cast toMyClass
. This is different from saying that it's an instance of that type, because it could be that myObject is an instance of a class that inherits fromMyClass
.Again, the
is
operator already checks the type on both operands, so you should go withif myObject is MyClass
.All that said, I'd like to explain the "theory" behind the type system. I'm no specialist, so I'm giving you a more practical explanation:
A class definition label (like
MyClass
) is not a System.Type. ASystem.Type
is a metadata class that is generated by the CLR to represent the type defined by your label. To retrieve theSystem.Type
related to a certain class definition label, use thetypeof
operator as follows:On a object instance, you can retrieve the
System.Type
metadata by calling the methodGetType()
on it. It will give you an instance ofSystem.Type
related to the class that represents the actual instance. This means that if your object is being treated by the compiler as a interface or a base class,.GetType()
still gives you the most derived type for that instance.You can compare
System.Type
in order to check if two objects are instances of the same class, but again, beware that your instance can be of a more derived type; The equality will fail (theSystem.Type
of a more derived class is different than that of a less derived one).If you need to take inheritance into account, you can use the method
IsAssignableFrom
, like this:C# and VB.Net gives you two operators that enables you to do type checking on the fly,
is
andas
.is
does automatic typing retrieval and is preferred over getting theSystem.Type
yourself. It accounts for inheritance as well:If you need to check the type and cast the object use
as
:What you cannot do with
as
is not perform proper result checking; The problem is that if you don't check it for null and use it, you get anNullReferenceException
, which will hide the correct problem (the cast failed). If you are sure you can do the cast, then use a explicit cast:This will throw an
InvalidCastException
, so the code will be easier to debug.如果该项为 null,则
.GetType()
方法可能会失败,因此您可能需要首先进行 null 检查。我不了解 VB,但在 C# 中,您将
is
与 object 一起使用,而不是它的类型 - 即is
之间的另一个区别(完成正确)和GetType()
/Equals
- 这里的区别在于子类。如果该项目实际上是一个SuperMyClass
(继承自MyClass
),则Equals
或==
将返回false
- 但是,is
将返回 true。typeof
仅限于与类型一起使用,而不是变量 - 即typeof(MyClass)
,但不能与一起使用类型(obj)
。如果您想要变量中对象的实际类型,请使用 obj.GetType()。就我个人而言,我会使用(在 C# 中):
因为这会进行类型检查并强制转换一次而不是两次
The
.GetType()
approach could fail if the item is null, so you might want a null check first.I don't know about VB, but in C# you use
is
with the object, not it's type - i.e.Another difference between
is
(done correctly) andGetType()
/Equals
- the difference here is subclasses. If the item is actually anSuperMyClass
(inherited fromMyClass
) thenEquals
or==
will returnfalse
- however,is
will return true.typeof
is restricted to use with types, not variables - i.e.typeof(MyClass)
, but nottypeof(obj)
. If you want the actual type of an object in a variable, useobj.GetType()
.Personally, I would use (in C#):
as this does a type-check and cast once rather than twice
综上所述,
is
对于类和子类都将为 true。例如:使用 Equals 和 typeof([ClassName]) 只等于类,而不等于子类:
To sum up,
is
will make true for class and subclass.For example:and use Equals and typeof([ClassName]) is just equal to class, not to subclass: