Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# IsAssignableFrom、IsInstanceOfType和is关键字有什么区别?_C#_C# 4.0_Casting - Fatal编程技术网

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);