C# IsAssignableFrom、IsInstanceOfType和is关键字有什么区别?
我有一个安全强制转换对象的扩展方法,如下所示:C# IsAssignableFrom、IsInstanceOfType和is关键字有什么区别?,c#,c#-4.0,casting,C#,C# 4.0,Casting,我有一个安全强制转换对象的扩展方法,如下所示: 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())) retu
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);
}
public static T SafeCastAs(此对象对象对象){
if(obj==null)
返回默认值(T);
//我应该用哪一个?
//1.可从
if(typeof(T).IsAssignableFrom(obj.GetType())
返回(T)obj;
//2.IsInstanceOfType
if(typeof(T).IsInstanceof type(obj))
返回(T)obj;
//3.是接线员吗
if(obj是T)
返回(T)obj;
返回默认值(T);
}
正如你所看到的,我有3个选择,那么我应该使用哪一个呢?实际上,
IsAssignableFrom
,IsInstanceOfType
,是
运算符之间的区别是什么 我猜您正在有效地实现一个版本的as
操作符,它既可以处理值类型,也可以处理引用类型
我会选择:
public static T SafeCastAs<T>(this object obj)
{
return (obj is T) ? (T) obj : default(T);
}
你使用你所掌握的信息 如果要检查实例和静态类型,请使用
is
如果没有静态类型,则只有一个type
对象,但有一个要检查的实例,请使用IsInstanceOfType
如果您没有实例,只想检查一个类型的理论实例与另一个类型的之间的兼容性,请使用IsAssignableFrom
但实际上,您似乎只是在重新实现(除了您的也适用于不可为null的值类型,这通常不是一个很大的限制)。我想您应该使用“”而不是自定义的“安全卡斯塔”。但这只适用于类(而不是结构),所以如果您也希望对结构使用此方法,我可以获得它
运算符“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
会产生不同的结果
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
有更多可能的组合可以尝试。例如,在本例中,您可以引入一个与现有类无关的类C。我不确定您在这里的断言是否正确typeof(int)
返回类型为type
的对象,因此第一条语句将失败,因为type
对象显然不是int
。但是,如果将第一条语句更改为a.GetType().IsInstanceOfType(3)
,它将返回true。我认为您在这里使用的IsInstanceOfType
是错误的。@JeffBridgman true,我想我只是试图说明使用这两种方法的区别,比如``Console.WriteLine(typeof(int?.IsInstanceOfType(null));Console.WriteLine(typeof(int?).IsInstanceOfType(1));Console.WriteLine(typeof(int?).IsAssignableFrom(typeof(int));`我将删除这个答案的一些部分。IsAssignableFrom和IsInstanceOfType之间还有一个额外的区别。在某些类型中,类型A可分配给类型B,即使类型B不是类型A的实例。例如:类B{}类D:B{}接口IGeneric{}typeof(IGeneric);