- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在编写一个通用方法以在 T4 模板的特殊任务中使用它。该方法应该允许我使用通用接口(interface)中的专用类型。我想到了以下签名:
interface IGreatInterface {
Object aMethodAlpha<U>(U parameter) where U : IAnInterface;
Object aMethodBeta(IAnInterface parameter)
}
public class AnInterestingClass : IAnInterface{}
当我尝试执行 IGreatInterface
时编译器为 aMethodBeta()
标记错误因为我已经让我的 T4 使用 IAnInterface
的子类型编写该方法(即我想像这样实现该方法:Object aMethodBeta(AnInterestingClass parameter)
)。
方法aMethodAlpha<U>()
可以使用,但没有我想要的那么干净,因为我的 T4 必须生成一些额外的代码。我(也许是错误的)建议该方法的实现,必须由 T4 完成,可以是
Object aMethodAlpha<AnInterestingClass>(AnInterestingClass parameter)
.
我认为泛型方法不支持逆变类型,但我不确定;我想这是编译器阻止编码器使用具有未在通用类型中定义的方法的特定类型的方式...
最佳答案
这个问题比较迷惑。让我看看是否可以澄清。
When I try to implement
IGreatInterface
the compiler flags an error foraMethodBeta()
because I've made that method using a subtype ofIAnInterface
I want to implement that method like this:Object aMethodBeta(AnInterestingClass parameter)
.
那是不合法的。稍微简化一下:
class Food {}
class Fruit : Food {}
class Meat : Food {}
interface IEater
{
void Eat(Food food);
}
class Vegetarian : IEater
{
public void Eat(Fruit fruit);
}
类 Vegetarian
不履行IEater
的契约(Contract).你应该能够通过任何食物来吃,但是Vegetarian
只接受水果。 C# 不支持虚方法形式参数协变,因为那不是类型安全的。
现在,你可能会说,这个怎么样:
interface IFruitEater
{
void Eat(Fruit fruit);
}
class Omnivore : IFruitEater
{
public void Eat(Food food);
}
现在我们有了类型安全; Omnivore
可以用作 IFruitEater
因为 Omnivore
可以吃水果,以及任何其他食物。
不幸的是,C# 不支持虚方法形式参数类型逆变,尽管这样做在理论上是类型安全的。很少有语言支持这一点。
同样,C# 也不支持虚方法返回类型变化。
我不确定这是否真的回答了您的问题。你能澄清一下这个问题吗?
更新:
关于:
interface IEater
{
void Eat<T>(T t) where T : Food;
}
class Vegetarian : IEater
{
// I only want to eat fruit!
public void Eat<Fruit>(Fruit food) { }
}
不,这也不合法。 IEater
的契约(Contract)是你将提供一个方法 Eat<T>
可以采取任何 T
那是一个Food
.你不能部分执行契约(Contract),你不能这样做:
interface IAdder
{
int Add(int x, int y);
}
class Adder : IAdder
{
// I only know how to add two!
public int Add(2, int y){ ... }
}
但是,您可以这样做:
interface IEater<T> where T : Food
{
void Eat(T t);
}
class Vegetarian : IEater<Fruit>
{
public void Eat(Fruit fruit) { }
}
这是完全合法的。但是,您不能这样做:
interface IEater<T> where T : Food
{
void Eat(T t);
}
class Omnivore : IEater<Fruit>
{
public void Eat(Food food) { }
}
同样,C#不支持虚方法形参逆变或协变。
请注意,C# 确实支持参数多态性协变,但已知这样做是类型安全的。例如,这是合法的:
IEnumerable<Fruit> fruit = whatever;
IEnumerable<Food> food = fruit;
水果序列可以用作食物序列。或者,
IComparable<Fruit> fruitComparer = whatever;
IComparable<Apples> appleComparer = fruitComparer;
如果你有东西可以比较任何两个水果,那么它就可以比较任何两个苹果。
但是,这种协变和逆变只有在满足以下所有条件时才合法:(1) 变型可证明是类型安全的,(2) 类型的作者添加了变型注释,表明所需的协变和逆变差异,(3) 涉及的可变类型参数都是引用类型,(4) 泛型类型是委托(delegate)或接口(interface)。
关于c# - 泛型方法可以使用逆变/协变类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8099833/
可以用这种方式转换字符串吗?我们有相同的参数,Java 做出了正确的选择。如果值是整数 - 我们调用 parseInt(value),否则如果值是 double 型 - 我们调用 parseDoubl
如果这段代码中有一个愚蠢的错误,我提前道歉,但我似乎无法解决它。我的问题是这样的,我用GCC-8(通过home-brew安装在Mac上)编译,然后在终端中执行。当使用 int do 定义变量 s &
我用 a-videosphere 制作了一个 a-scene。我尝试使用按钮启用/禁用声音,但有些想法不起作用?这是我的代码: var gargamel = 0; function
我正在使用 ISAAC 实现来生成随机整数。我需要用这些整数创建一个高斯值。首先,我需要将它们从 0 更改为 1 的 double 值。我怎样才能在Java中做到这一点?这是到目前为止我将整数转换为
我将 0x0000 到 0x01c2 范围内的十六进制值从 BLE 获取到我的手机 a 作为字符串。为了将其绘制在图表中,我必须将其转换为 double,我已经尝试过 this method但遗憾的是
我有一个父类(super class) Animal和一个子类 Dog 。在第三节课中,我有一个 List它同时接受子类型和父类(super class)型对象。 public class foo{
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 6 年前。 Improve this ques
我正在尝试查询我的用户的距离。我可以用这段代码做到这一点 PFGeoPoint.geoPointForCurrentLocationInBackground { (geoPoint: PFGe
考虑示例:http://jsfiddle.net/KWLu7/16/ 我正在尝试将总体重要性值计算为每个选定选择重要性的总和乘以其父标准重要性: var watch = $scope.$watch("
这个问题在这里已经有了答案: Bounding generics with 'super' keyword (6 个答案) 关闭 2 年前。 我有一个列表装饰器,它应该允许从一个列表转换到另一个列表
为什么下面的代码没有选择最近父类(super class)型的隐式 val? class A class B extends A trait TC[-T] { def show(t: T): Stri
这是我想要做的 def merge[A, B, C](eithers: Either[A,B]*)(implicit ev1: A x, x => x)) 关于scala - 推断常见的父类(s
我正在尝试从具有 double 类型列的Cassandra表中获取 double 值。我已经使用CQL3语法创建了表: CREATE TABLE data_double ( datetime
是否应该在不需要显式类型定义的情况下编译以下 this ? def prepList[B >: A](prefix: PlayList[B]) : PlayList[B] = prefix.fol
我正在查看某人的代码,并且在创建结构时使用了 abstract type AbstractFoo end julia> struct Foo1 struct Foo2 foo_op(x::Abst
一些示例代码: public class Main { class SomeType { } class A { protected T createSome
是否可以只接受类的泛型类型的父类(super class)型? 我正在寻找的是这样的: class MyClass { public void myMethod(TS someObject
在我的代码中,我有许多 ArrayList 被传递到排序方法中。每个 ArrayList 都有不同的泛型类型,但所有这些类型都是 Sorter 的实现。排序方法旨在接受 Sorter 类型的 Arra
如果已经有人问过这个问题,请链接并关闭这个问题。 我目前正在为另一个使用起来复杂得多(并且有潜在危险)的 API 的简化 API 设计原型(prototype)。 考虑到相关的有点复杂的对象创建,我决
我正在尝试构建一个具有某些依赖项的 android 应用程序,但是其中一个导致了此错误: Illegal class file: Class module-info is missing a supe
我是一名优秀的程序员,十分优秀!