gpt4 book ai didi

c# - 通用参数不可分配

转载 作者:太空狗 更新时间:2023-10-30 00:07:40 27 4
gpt4 key购买 nike

我正在使用 C#.NET 3.5。我明白了

argument type 'GenericTest.BarkStrategy' is not assignible to parameter type 'GenericsTest.IAnimalStrategy'

使用以下(对于这个问题尽可能简化)代码:

using System.Collections.Generic;

namespace GenericsTest {
class Program {
static void Main(string[] args) {
List<IAnimalStrategy<IAnimal>> strategies =
new List<IAnimalStrategy<IAnimal>>();
strategies.Add(new BarkStrategy());
}
}

interface IAnimal { }
interface IAnimalStrategy<T> where T : IAnimal { }
class Dog : IAnimal { }
class BarkStrategy : IAnimalStrategy<Dog> { }
}

最佳答案

你必须告诉编译器你的接口(interface)是协变的:IAnimalStrategy<out T>

namespace GenericsTest
{
class Program
{
static void Main(string[] args)
{
List<IAnimalStrategy<IAnimal>> strategies = new List<IAnimalStrategy<IAnimal>>();
strategies.Add(new BarkStrategy());
}
}

interface IAnimal { }
interface IAnimalStrategy<out T> where T : IAnimal { }

class Dog : IAnimal { }
class BarkStrategy : IAnimalStrategy<Dog> { }
}

不幸的是,它仅在 C# 4.0 中可用:How is Generic Covariance & Contra-variance Implemented in C# 4.0?

为了理解问题,你可以忘记列表,这一行不编译:

IAnimalStrategy<IAnimal> s = new BarkStrategy();

IAnimalStrategy<IAnimal> 接口(interface)可以在 IAnimal 上做一些事情,也许可以设置一个 IAnimal 类型的属性

interface IAnimalStrategy<T> where T : IAnimal 
{
T Animal {get; set;}
}

然后你就可以做类似的事情了

IAnimalStrategy<IAnimal> s = new BarkStrategy();
s.Animal = new Cat();

它会吹到你的脸上。所以 C#3.5 不允许你这样做。
如果您说 T 与 out 关键字协变,C#4.0 将允许您这样做

interface IAnimalStrategy<out T> where T : IAnimal 
{
T Animal {get; set;}
}

又要吹了,

Invalid variance: The type parameter 'T' must be invariantly valid onIAnimalStrategy.Animal'. 'T' is covariant.

Covariance 和 Contravariance 很难理解,我建议你阅读 Eric Lippert 博客上的精彩系列:Covariance and Contravariance in C#

关于c# - 通用参数不可分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19541699/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com