c# - 将 where 约束与通用接口(interface)或类一起使用

标签 c# .net

假设我们写了一个测试系统。测试包含任务列表,每个任务包含问题和答案列表。我们还假设问题或答案不仅可以是文本,还可以是图像。所以我们使用泛型:

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> , 但这样你就可以拥有 TQuestionIQuestion<string> .


附录:有TQuestionIQuestion<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/

相关文章:

c# - 因为它有一个 DefiningQuery 并且 <ModificationFunctionMapping> 元素中不存在 <InsertFunction> 元素

c# - 没有添加的公共(public)列表

c# - 如何保护与 MySql 服务器的连接

c# - WCF SslStreamSecurity DNS 身份检查仅针对 4.6 框架失败

c# - .NET 线程 - 快速提问

C# 将工具提示设置为 <asp :Label> or a <asp:Literal>

c# - 在 Visual Studio Code 中找不到 Xunit 命名空间

c# - Azure 搜索 SDK 创建数据源

c# - global_asax 在命名空间 ASP 中不存在

c# - 我必须 Invoke() 才能显示线程中的对话框或 MessageBox 吗?