IsAssignableFrom, IsInstanceOfType和is关键字有什么区别?
本文关键字:什么 区别 关键字 is IsInstanceOfType IsAssignableFrom | 更新日期: 2023-09-27 18:07:40
我有一个扩展方法来安全转换对象,看起来像这样:
public static T SafeCastAs<T>(this object obj) {
if (obj == null)
return default(T);
// which one I should use?
// 1. IsAssignableFrom
if (typeof(T).IsAssignableFrom(obj.GetType()))
return (T)obj;
// 2. IsInstanceOfType
if (typeof(T).IsInstanceOfType(obj))
return (T) obj;
// 3. is operator
if (obj is T)
return (T) obj;
return default(T);
}
如你所见,我有3个选择,那么我应该用哪一个呢?实际上IsAssignableFrom
, IsInstanceOfType
和is
算子有什么区别?
你可以用任何你知道的信息。
如果您想要检查一个实例和一个静态类型,请使用is
。
如果你没有静态类型,你只有一个Type
对象,但你有一个实例,你想检查,使用IsInstanceOfType
。
如果你没有实例,你只是想检查Type
和另一个Type
的理论实例之间的兼容性,使用IsAssignableFrom
。
但实际上似乎只是重新实现了as操作符(除了您的操作符也适用于非空值类型,这通常不是一个大的限制)。
我猜你是在有效地实现as
操作符的一个版本,它可以与值类型和引用类型一起工作。
我会选:
public static T SafeCastAs<T>(this object obj)
{
return (obj is T) ? (T) obj : default(T);
}
IsAssignableFrom
适用于类型,is
适用于实例。在你的情况下,它们会给你相同的结果,所以我认为你应该使用最简单的版本。
对于IsInstanceOfType
:这是按照IsAssignableFrom
来实现的,所以不会有区别。
你可以通过使用Reflector来查看IsInstanceOfType()
的定义来证明:
public virtual bool IsInstanceOfType(object o)
{
if (o == null)
{
return false;
}
return this.IsAssignableFrom(o.GetType());
}
我想你应该用"as"代替你的自定义"SafeCastAs"。但这将只适用于类(不是结构),所以如果你想使用这种方法的结构以及我可以得到它。
操作符"is"基本上提供了与Type相同的功能。IsAssignableFrom,所以你可以只保留"is",它检查你是否可以安全地将obj转换为T,没有异常。所以它会在你的方法中覆盖之前的检查。但是您应该注意,由于用户定义的转换:显式和隐式关键字,它不会检查您是否可以将obj分配给T。
这些函数和操作符具有不同的含义。如果你有对象,你总能得到类型。所以你不是在做你已经做的事,而是在做你需要做的事。
当你在处理一个类的层次结构时,差异是非常明显的。
看下面的例子
class ABase
{
}
class BSubclass : ABase
{
}
ABase aBaseObj = new ABase();
BSubclass bSubclassObj = new BSubclass();
ABase subObjInBaseRef = new BSubclass();
不同的操作产生不同的结果。
typeof(ABase).IsInstanceOfType(aBaseObj) = True
typeof(ABase).IsInstanceOfType(bSubclassObj) = True
typeof(ABase).IsInstanceOfType(bSubclassObj) = True
typeof(BSubclass).IsInstanceOfType(aBaseObj) = False
bSubclassObj is ABase = True
aBaseObj is BSubclass = False
subObjInBaseRef is BSubclass = True
subObjInBaseRef is BSubclass = True
typeof(ABase).IsAssignableFrom(typeof(BSubclass)) = True
typeof(BSubclass).IsAssignableFrom(typeof(ABase))= False
在没有层次结构的情况下,可能一切都是相同的。但是如果使用层次结构,IsAssignableFrom
、is和IsInstanceOfType
会产生不同的结果。
有更多可能的组合可以尝试。例如,您可以引入一个与本例中现有类没有任何关系的类C。