我对 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#都可以,上面的代码是伪代码。
最佳答案
首先让我们看看您给出的三个选项:
If myObject.GetType.Equals(MyClass)
这可能会导致错误,因为 equals 需要一个 System.Type
,而不是一个类。类定义不是 System.Type
,但您可以使用 typeof
运算符检索它。所以你可以执行 instance.Equals(typeof(MyClass))
,如果对象属于给定类,它会返回 true。
If TypeOf(myObject) Is MyClass
相反,您不能对实例使用 typeof
,只能对类使用,所以上面的代码会失败。此外,is
运算符会自动检查类型,因此您在使用它时不能执行 typeof
或 GetType
。您应该使用 if myObject is MyClass
,如果 myObject 可以转换为 MyClass
,它将返回 true。这不同于说它是该类型的实例,因为它可能是 myObject 是从 MyClass
继承的类的实例。
If myObject.GetType() Is MyClass
同样,is
运算符已经检查了两个操作数的类型,因此您应该使用 if myObject is MyClass
。
综上所述,我想解释一下类型系统背后的“理论”。我不是专家,所以我给你一个更实际的解释:
类定义标签(如
MyClass
)不是 System.Type。System.Type
是由 CLR 生成的元数据类,用于表示标签定义的类型。要检索与某个类定义标签相关的System.Type
,请使用typeof
运算符,如下所示:System.Type MyClassType = typeof(MyClass);
在对象实例上,您可以通过调用方法
GetType()
来检索System.Type
元数据。它将为您提供与表示实际实例的类相关的System.Type
实例。这意味着,如果编译器将您的对象视为接口(interface)或基类,.GetType()
仍会为您提供该实例的派生程度最高的类型。您可以比较
System.Type
以检查两个对象是否是同一类的实例,但同样要注意您的实例可能是更派生的类型;相等性会失败(派生程度高的类的System.Type
与派生程度低的类的不同)。如果需要考虑继承,可以使用方法
IsAssignableFrom
,像这样:BaseClass instance = new DerivedClass(); System.Type type = instance.GetType(); if ((typeof(BaseClass)).IsAssignableFrom(type)) // returns true { }
C# 和 VB.Net 为您提供了两个运算符,使您能够即时进行类型检查,
is
和as
。is
进行自动类型检索,优于自己获取System.Type
。它也解释了继承:DerivedClass instance = new DerivedClass(); System.Type type = instance.GetType(); if (instance is BaseClass) // returns true { }
如果您需要检查类型并转换对象使用
as
:DerivedClassinstance = new DerivedClass(); System.Type type = instance.GetType(); AnotherClass another = instance as AnotherClass; if (another == null) // returns true { // Do proper error treatment... throw an exception or something }
不能用
as
做的是不执行正确的结果检查;问题是,如果您不检查它是否为 null 并使用它,您将得到一个NullReferenceException
,这将隐藏正确的问题(转换失败)。如果您确定可以进行强制转换,则使用显式强制转换:DerivedClassinstance = new DerivedClass(); System.Type type = instance.GetType(); AnotherClass another = (AnotherClass)instance; // throws
这将抛出一个
InvalidCastException
,因此代码将更容易调试。
关于c# - 这段代码能正确判断两种类型是否相等吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6073698/