繁体   English   中英

为什么在某些一般情况下必须进行铸造?

[英]Why is casting in certain generic circumstances necessary?

在通用方法中,您需要将返回变量转换为对象,然后再转换为通用类型,我理解这通常是为什么,但是我不明白的是为什么在建立了什么之后就需要这样做类型变量在return语句的范围内。 例如,通常我会这样做:

public MyType1 obj1;
public MyType2 obj2;

public T GetObject<T>()
{
    if (obj1 is T) return (T)(object)obj1;
    else if (obj2 is T) return (T)(object)obj2;
    else return default(T);
}

但是我的问题是,为什么不能这样删除演员表:

public MyType1 obj1;
public MyType2 obj2;

public T GetObject<T>()
{
    if (obj1 is T) return obj1;
    else if (obj2 is T) return obj2;
    else return default(T);
}

当唯一的类型是对象时,为什么编译器不理解该对象的返回类型正确?

您对泛型做出了错误的假设。 为了更好地理解这一点,请想象一下。 假设您有一个基类Base和两个子类Sub和VerySub。

如果您的成员存储为Base,则编译器只能保证它们是Base。 这是泛型使用的静态类型系统。 假设在运行时,我们有一个简单的函数GetIfVerySub。 假设它对Base类型的对象进行了测试,发现它也是VerySub。 在编译时这是不可知的,因此要返回向下转换的对象,您可能希望进行强制转换或as。

这正是您的泛型函数正在尝试做的事情,但是由于它是泛型的,因此它也可以在任何类型上工作,包括与Base不兼容的类型。

不过,更好的问题是,为什么要这么做呢?

根据C#参考

如果已知表达式始终为true或始终为false则is关键字会引起编译时警告,但通常会在运行时评估类型兼容性。

那就是obj1是否为T类型,不是由编译器确定的,而是在代码运行时评估的。

避免foo is T; (T)foo foo is T; (T)foo表达式。 使用as运算符可以解决您的问题:

public MyType1 obj1;

public T GetObject<T>() where T : class {
    T ret = obj1 as T;
    if( ret != null ) return ret;
    ret = obj2 as T;
    if( ret != null ) return ret;
    return default(T);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM