假设我们写了一个测试系统。测试包含任务列表,每个任务包含问题和答案列表。我们还假设问题或答案不仅可以是文本,还可以是图像。所以我们使用泛型:
public interface IQuestion<T>
{
T Content { get; }
}
public interface IAnswer<T>
{
T Content { get; }
bool IsCorrect { get; }
}
问题出现在我们创建任务的时候:
interface ITask<TQuestion, TAnswer>
{
TQuestion Question { get; }
List<TAnswer> Answers { get; }
}
怎么写TQuestion
应该是 IQuestion
的子类型和 TAnswer
- IAnswer
的子类型?
我试过:
interface ITask<TQuestion, TAnswer>
where TQuestion : IQuestion<object>
where TAnswer : IAnswer<object>
但是当我创建时:
class TextQuestion : IQuestion<string> {...}
class TextAnswer : IAnswer<string> {...}
这没有用:
class TextTask : ITask<TextQuestion, TextAnswer>
因为,事实上,IQuestion<string>
不要继承自 IQuestion<object>
.
在 Java 中,我会在 ITask
的限制中使用通配符泛型类型,在 Kotlin 中,上述方法会奏效。
但是如何用C#解决呢?
最佳答案
你需要第三个参数:
interface ITask<TQuestion, TAnswer, T>
where TQuestion : IQuestion<T>
where TAnswer : IAnswer<T>
如您所知,IQuestion<string>
不要继承自 IQuestion<object>
, 但这样你就可以拥有 TQuestion
是IQuestion<string>
.
附录:有TQuestion
是IQuestion<object>
只是一个问题,因为 IQuestion
没有 variance已定义(因此,默认情况下它是不变的)。如果你定义如下所示,你可以使用 IQuestion<object>
(同样适用于 IAnswer
)。
public interface IQuestion<out T>
{
T Content { get; }
}
public interface IAnswer<out T>
{
T Content { get; }
bool IsCorrect { get; }
}
interface ITask<TQuestion, TAnswer>
where TQuestion : IQuestion<object>
where TAnswer : IAnswer<object>
{
TQuestion Question { get; }
List<TAnswer> Answers { get; }
}
关于c# - 将 where 约束与通用接口(interface)或类一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42409982/