首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >参数类型X不能分配给泛型类型T,其中X指定为where子句

参数类型X不能分配给泛型类型T,其中X指定为where子句
EN

Stack Overflow用户
提问于 2016-06-13 08:01:06
回答 2查看 1.2K关注 0票数 1

我有以下课程

代码语言:javascript
复制
public class CalculatorManipulator<TCalculator>
        where TCalculator : CachableCalculator

它包含一本字典:

代码语言:javascript
复制
   protected Dictionary<string, TCalculator> Calculators { get; set; }

假设我试图添加这样的项目

代码语言:javascript
复制
Calculators.Add(calc.CustomCaption, new CachableCalculator(calc, fg, cache));

为什么这会产生编译时错误:

代码语言:javascript
复制
Argument type CachableCalculator is not assignable to parameter type TCalculator.

编译器知道TCalculatorCachableCalculator

我想知道为什么我要投它,因为它可以自动完成它。

这是通过将其转换到TCalculator来实现的。

代码语言:javascript
复制
     Calculators.Add(calc.CustomCaption, (TCalculator)new CachableCalculator(calc, fg, cache));
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-13 08:03:56

DogAnimal;这并不意味着您可以假设任何Animal都是Dog,并将所有东西都扔到狗舍中。

其中:TCalculatorDogCachableCalculatorAnimal。将TCalculator作为CachableCalculator来处理是可以的,但反过来处理是可以的:您需要通过添加显式强制转换来告诉编译器您知道自己在做什么。

票数 6
EN

Stack Overflow用户

发布于 2016-06-13 08:16:12

为了更清楚地说明这一点,假设您拥有以下内容:

代码语言:javascript
复制
class Animal
{
}

class Dog : Animal
{
}

class AnimalManipulator<TAnimal> where TAnimal : Animal
{
    readonly Dictionary<string, TAnimal> animals = new Dictionary<string, TAnimal>();

    public void Test()
    {
        // Here you are forced to cast to the dictionary value type, because
        // what you are doing is NOT SAFE:
        animals.Add("Animal", (TAnimal)new Animal());
    }
}

现在我们可以说明为什么上面的代码是不安全的:

代码语言:javascript
复制
var test = new AnimalManipulator<Dog>();
test.Test(); // Runtime exception.

在本例中,TAnimal的类型是Dog,就泛型约束TAnimal : Animal而言,这是可以的。

但是,当您调用Test()时,代码将尝试将Animal转换为Dog,这当然是不允许的。

就您的类型而言,您可以有一个派生自CachableCalculator的类,并将其与您的CalculatorManipulator一起使用,这将导致等效的异常。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37784515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档