c# - 使用类型参数约束实现两次相同的通用接口(interface)

标签 c# generics interface constraints

拥有

public interface IGeneric<T>{}

public class Student{}

public class Teacher{}

这是可能的

public class ConcreateClass : IGeneric<Student>, IGeneric<Teacher>{}

这是不可能的

public class GenericClass<T1, T2> : IGeneric<T1>, IGeneric<T2> {}

因为GenericClass<String, String> instance;会导致两个接口(interface)实现的歧义。但为什么这是不可能的

public class GenericClassWithTypeConstraints<T1, T2> : IGeneric<T1>, IGeneric<T2>
    where T1 : Student
    where T2 : Teacher
{}

因为 T1 和 T2 不能属于同一类? (编译错误和没有类型约束的情况一样)

编辑
Why does this result in CS0695 中的“Soner Gönül”提出了一种解决方法,使用两级类继承,如下所示:

public interface IGeneric<T> { String Name { get; } }

public class Student{}

public class Teacher{}

public class GenericClassBase<T1> : IGeneric<T1>
    where T1 : Student
{ String IGeneric<T1>.Name { get { return "Generic class of Student"; } } }

public class GenericClassDerived<T1, T2> : GenericClassBase<T1>, IGeneric<T2>
    where T1 : Student
    where T2 : Teacher
{ String IGeneric<T2>.Name { get { return "Generic class of Teacher"; } } }

像这样的代码然后产生预期的结果

GenericClassDerived<Student, Teacher> X = new GenericClassDerived<Student, Teacher>();
Console.WriteLine(((IGeneric<Student>)X).Name); //outputs "Generic class of Student"
Console.WriteLine(((IGeneric<Teacher>)X).Name); //outputs "Generic class of Teacher"

最佳答案

as T1 and T2 cannot be of the same class?

是的,他们可以是同一个类(class)。约束不能是 sealed classes1 所以 Teacher 可以从 Student 派生,反之亦然。这不合逻辑,但编译器对此一无所知。

例如,

using System;

public class Student{}

public class Teacher : Student{}

public class GenericClassWithTypeConstraints<T1, T2>
    where T1 : Student
    where T2 : Teacher
{}

class Test {
    static void Main() {
        var obj = new GenericClassWithTypeConstraints<Teacher, Teacher>();
    }
}

编译没有任何问题。 Demo


  1. Docs:

    Constraints can also be class types, such as abstract base classes. However, constraints cannot be value types or sealed classes.

关于c# - 使用类型参数约束实现两次相同的通用接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15804926/

相关文章:

c# - 在 x86 模式下构建 MVC6/ASP.Net 5 项目

c# - .NET 6 使记录中的属性为必需且非空的最佳方法是什么

java - 可能的 eclipse 错误

java - 重写接口(interface)方法时删除 Java 检查异常?

cocoa - 下拉窗口编辑 Cocoa 弹出菜单项

c# - 从带参数的电子邮件启动 ClickOnce 应用程序

c# - 不卡住 Thread.Sleep 的替代品,用于在任务中等待

java - 将 Collection 和 Iterator 接口(interface)实现为内部类

java - 如何使用java反射获取列表的泛型类?

android - Android 中的响应式设计与外部图像?