gpt4 book ai didi

使用接口(interface)的泛型进行 C# 转换

转载 作者:太空狗 更新时间:2023-10-29 22:11:14 25 4
gpt4 key购买 nike

我有一些通用接口(interface)和实现这些接口(interface)的类,如下所示:

    interface A<M, N>
where M : X<N>
where N : Y
{
}
class B<M, N> : A<M, N>
where M : X<N>
where N : Y
{

}

interface X<M> where M : Y
{

}
interface Y
{

}
class X1<M> : X<M> where M : Y
{

}
class Y1 : Y
{

}

我知道这似乎是一种非常困惑的做事方式,但我的应用程序需要它。我的问题是为什么我不能这样做:

A<X<Y>, Y> variable = new B<X1<Y1>, Y1>();

最佳答案

马克是对的;只是为了让您了解为什么这行不通的更多背景知识。考虑对您的代码进行以下重命名:

    interface IZoo<TCage, TAnimal>
where TCage : ICage<TAnimal>
where TAnimal : IAnimal
{
}

class Zoo<TCage, TAnimal> : IZoo<TCage, TAnimal>
where TCage : ICage<TAnimal>
where TAnimal : IAnimal
{
}

interface ICage<TAnimal> where TAnimal : IAnimal
{
}

interface IAnimal
{
}

class FishTank<TAnimal> : ICage<TAnimal> where TAnimal : IAnimal
{
}

class Fish : IAnimal
{
}

现在你的问题是,为什么这不合法:

Zoo<FishTank<Fish>, Fish> aquarium = new Zoo<FishTank<Fish>, Fish>();
IZoo<ICage<IAnimal>, IAnimal> zoo = aquarium;

?

因为假设现在 IZoo 上有一个方法:

    interface IZoo<TCage, TAnimal>
where TCage : ICage<TAnimal>
where TAnimal : IAnimal
{
void PutAnimalInCage(TCage cage, TAnimal animal);
}

然后你说:

zoo.PutAnimalInCage(giraffePaddock, giraffe);

而您只是将长颈鹿围场放入水族馆!在您想要的转换是合法的并且 IZoo 可以使用您选择的任何方法的世界中,我们无法维护类型安全。

现在,这只是危险的,因为 IZoo 有这样的方法。如果它没有这样的方法那么你是对的,那可能是非常安全的。在 C# 4.0 中,我们向该语言添加了一项功能,以便您可以通过注释您希望与“out”协变的类型参数以及您想要与“in”是逆变的。如果你这样做,那么编译器会为你检查你想要的变化是否可以是类型安全的。如果不能,则不允许声明该类型。

这个问题通常出现在 StackOverflow 上的方式是人们问为什么这是非法的:

List<Giraffe> giraffes = new List<Giraffe>();
List<Mammal> mammals = giraffes; // illegal

同理。因为这样就没有什么能阻止你以后了

mammals.Add(new Tiger());

您刚刚在长颈鹿列表中添加了一只老虎。同样的推理,只是一个简单得多的案例。

关于使用接口(interface)的泛型进行 C# 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5935224/

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