c# - 为什么我不能将对象转换为受约束的泛型?

标签 c# generics casting

鉴于我有以下接口(interface)和一个实现它的类:

public interface IAnimal
{
    void Feed();
}

public class Animal : IAnimal
{
    public void Feed()
    {
        // feed
    }
}

当我的 Animal 类实现它时,为什么不能从我的具体类转换为约束为 IAnimal 的泛型?

public class Zoo
{
    private readonly Animal animal = new Animal();

    public TAnimal GetAnimal<TAnimal>() where TAnimal : IAnimal
    {
        return (TAnimal)(this.animal); // This will not compile
    }
}

如果我将 animal 的字段类型更改为 IAnimal 而不是 Animal,那么它可以编译:

public class Zoo
{
    private readonly IAnimal animal = new Animal();

    public TAnimal GetAnimal<TAnimal>() where TAnimal : IAnimal
    {
        return (TAnimal)(this.animal); // this compiles
    }
}

或者,如果我在转换为通用 TAnimal 之前对 IAnimal 进行显式转换,那么这也可以正常编译:

public class Zoo
{
    private readonly Animal animal = new Animal();

    public TAnimal GetAnimal<TAnimal>() where TAnimal : IAnimal
    {
        return (TAnimal)((IAnimal)this.animal); // this compiles
    }
}

所以我的问题是 - 为什么第一个版本不起作用?编译器肯定有足够的信息知道 Animal 实现了 IAnimal,所以给定约束将其转换为 TAnimal 是否有效?还是我在这里遗漏了什么?

最佳答案

Animal 继承自 IAnimalTAnimal 不是继承自 Animal,而是继承自 IAnimal 也是。如果 B 没有继承自 A,则不能从 A 转换为 B,这将是一些喜欢:

DataTable dt = new DataTable();
string str = (string)dt;

即使 DataTablestring 继承自 object,您也不能这样做。要在不通过继承关联的类型之间进行转换,您必须定义 conversion operators

关于c# - 为什么我不能将对象转换为受约束的泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33035168/

相关文章:

c# - 在 C# 中 ZedGraph 中的图形数据上光标时显示 x、y 和曲线名称

c# - 当控件获得焦点时更新 ViewModel 中的属性

c# - foreach 与 someList.ForEach(){}

java - 如何为 Swagger API 响应指定泛型类型类

java - 泛型数组和泛型值有什么区别?

C# 错误还是脑筋急转弯? Cast 仅与 Coalesce (??) 运算符一起使用

c# - 如何使用 NodaTime 将 IANA zone + datetime 转换为 UTC + Offset

generics - 问号在类型参数绑定(bind)中意味着什么?

c++ - 枚举为无符号整数

c# - 带有 Unauthorize 状态代码和 Content//response 的 HttpResponseMessage 没有必需的 WWW-Authenticate header 字段