我在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#没问题,上面的代码是伪代码。
答案 0 :(得分:15)
如果该项为null,则.GetType()
方法可能会失败,因此您可能需要先进行空检查。
我不知道VB,但是在C#中你使用is
和对象,而不是它的类型 - 即。
if(obj is MyClass) {...}
is
(正确完成)和GetType()
/ Equals
之间的另一个区别 - 这里的区别是子类。如果该项目实际上是SuperMyClass
(继承自MyClass
),那么Equals
或==
将返回false
- 但是,is
将返回true
typeof
仅限于与类型一起使用,而不是变量 - 即typeof(MyClass)
,而不是typeof(obj)
。如果您想要变量中对象的实际类型,请使用obj.GetType()
。
就个人而言,我会使用(在C#中):
var typed = obj as MyClass;
if(typed != null) {
// do something interesting with typed
}
因为这会进行类型检查并进行一次而不是两次
答案 1 :(得分:14)
Fist让我们来看看你给出的三个选项:
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);
在对象实例上,您可以通过调用System.Type
方法来检索GetType()
元数据。它将为您提供与表示实际实例的类相关的System.Type
实例。这意味着如果您的对象被编译器视为接口或基类,.GetType()
仍然为您提供该实例的最多派生类型。
您可以比较System.Type
以检查两个对象是否是同一个类的实例,但同样要注意您的实例可以是更多派生类型;相等性将失败(更加派生的类的System.Type
与较少派生的类的BaseClass instance = new DerivedClass();
System.Type type = instance.GetType();
if ((typeof(BaseClass)).IsAssignableFrom(type)) // returns true
{
}
不同。
如果您需要考虑继承,可以使用方法IsAssignableFrom,如下所示:
代码:
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
无法对NullReferenceException
执行的操作未执行正确的结果检查;问题是,如果你没有检查它并使用它,你得到一个DerivedClassinstance = new DerivedClass();
System.Type type = instance.GetType();
AnotherClass another = (AnotherClass)instance; // throws
,这将隐藏正确的问题(转换失败)。如果您确定可以进行演员表演,那么请使用明确的演员:
InvalidCastException
这将抛出{{1}},因此代码将更容易调试。
答案 2 :(得分:0)
总而言之,is
将对类和子类生效。例如:
class B:Program{}
class Program{}
Program a = new Program();
B b = new B();
if (b is Program) ; // true
if (a is Program) ; // true
if (a is B) ; // false
if (b is B) ; //false
并使用Equals和typeof([ClassName])等于class,而不是子类:
class B:Program{}
class Program{}
Program a = new Program();
B b = new B();
if (b.GetType() == typeof(program)) ; // false
if (b.GetType() == typeof(B)) ; // true
if (a.GetType() == typeof(B)) ; // false
if (a.GetType() == typeof(Program)) ; //true