C# 我可以在泛型类中使用不相关的类型作为约束吗?

C# 我可以在泛型类中使用不相关的类型作为约束吗?,c#,.net,generics,C#,.net,Generics,我想创建一个泛型类,其中T参数可以是其他类型集中的任何实例。 所以这段代码编译得很好: 公共接口测试{} 公共接口TestB{} 公共类测试,其中T:TestA,TestB { } 然而,当我尝试这样使用它时 var a=新测试(); var b=新测试(); 我得到两个编译错误: 错误1类型“TestA”不能用作中的类型参数“T” 泛型类型或方法“测试”。没有隐式引用 从“TestA”到“TestB”的转换 错误2类型“TestB”不能用作中的类型参数“T” 泛型类型或方法“测试”。没有隐

我想创建一个泛型类,其中T参数可以是其他类型集中的任何实例。 所以这段代码编译得很好:

公共接口测试{}
公共接口TestB{}
公共类测试,其中T:TestA,TestB
{
}
然而,当我尝试这样使用它时

var a=新测试();
var b=新测试();
我得到两个编译错误:

错误1类型“TestA”不能用作中的类型参数“T” 泛型类型或方法“测试”。没有隐式引用 从“TestA”到“TestB”的转换

错误2类型“TestB”不能用作中的类型参数“T” 泛型类型或方法“测试”。没有隐式引用 从“TestB”到“TestA”的转换


我不明白为什么这不起作用。我如何解决这个问题?理想情况下,我希望TestA和TestB类没有关系(例如,它们之间没有继承)。

您指定该类必须实现这两个接口。所以您必须给它一个实现两个接口的类,而不仅仅是a或B

public class LikeThis : TestA, TestB
{

  // have both A and B's properties, methods, etc.
}

var a = new Test<LikeThis>();
类似这样的公共类:TestA、TestB { //同时具有A和B的属性、方法等。 } var a=新测试(); 另一个选项是使TestA和TestB都从基本接口继承

public interface IBaseInterface  { }
public interface IInterfaceA { }
public interface IInterfaceB { }

public class Test<T> where T : IBaseInterface
{

}

var a = new Test<IBaseInterface>();
公共接口IBaseInterface{}
公共接口IIinterfaceA{}
公共接口IIinterfaceB{}
公共类测试,其中T:IBaseInterface
{
}
var a=新测试();
但很难说你想在这里完成什么。测试类可能将对IBaseInterface的引用作为属性保存,但它不知道它是InterfaceA还是InterfaceB


如果你告诉我们你想实现什么,我们可以建议一个更好的解决方案。

你指定类必须实现两个接口。所以您必须给它一个实现两个接口的类,而不仅仅是a或B

public class LikeThis : TestA, TestB
{

  // have both A and B's properties, methods, etc.
}

var a = new Test<LikeThis>();
类似这样的公共类:TestA、TestB { //同时具有A和B的属性、方法等。 } var a=新测试(); 另一个选项是使TestA和TestB都从基本接口继承

public interface IBaseInterface  { }
public interface IInterfaceA { }
public interface IInterfaceB { }

public class Test<T> where T : IBaseInterface
{

}

var a = new Test<IBaseInterface>();
公共接口IBaseInterface{}
公共接口IIinterfaceA{}
公共接口IIinterfaceB{}
公共类测试,其中T:IBaseInterface
{
}
var a=新测试();
但很难说你想在这里完成什么。测试类可能将对IBaseInterface的引用作为属性保存,但它不知道它是InterfaceA还是InterfaceB


也许,如果您告诉我们您试图实现的目标,我们可以建议一个更好的解决方案。

类型必须遵循泛型类型上定义的所有约束(AND、not或)

如果希望同时允许TestA或TestB,则应定义一个基本接口:

public interface TestBase { }
public interface TestA : TestBase { }
public interface TestB : TestBase { }
public class Test<T> where T : TestBase
{

}
公共接口测试库{}
公共接口TestA:TestBase{}
公共接口TestB:TestBase{}
公共类测试,其中T:TestBase
{
}

该类型必须遵循通用类型上定义的所有约束(AND、not或)

如果希望同时允许TestA或TestB,则应定义一个基本接口:

public interface TestBase { }
public interface TestA : TestBase { }
public interface TestB : TestBase { }
public class Test<T> where T : TestBase
{

}
公共接口测试库{}
公共接口TestA:TestBase{}
公共接口TestB:TestBase{}
公共类测试,其中T:TestBase
{
}

类型参数上的约束是合取的(AND),因此此处使用的任何类型都必须实现这两个接口

如前所述,一种方法是为两个接口创建一个超级接口,并将您的类型参数约束到该接口(请注意,我添加了常用的接口前缀
I
):

现在,
测试
超类不能从程序集外部继承(它有一个
内部
构造函数)。您的类(
Test1
Test2
)只使用超类的逻辑,每个类都使用一个所需的接口作为约束。客户端代码必须根据他们想要使用的接口约束来选择使用哪一个

此外,如果您的接口中有希望在
测试中使用的通用代码,则应将其提取到超级接口,并使您的超级类受其约束,从而实现两种方法的混合:

public interface IBase { }
public interface ITestA : IBase { }
public interface ITestB : IBase { }
public abstract class Test<T> where T : IBase {
    internal Test() { }
}
public class Test1<T> : Test<T> where T : ITestA { }
public class Test2<T> : Test<T> where T : ITestB { }
公共接口IBase{}
公共接口ITestA:IBase{}
公共接口ITestB:IBase{}
公共抽象类测试,其中T:IBase{
内部测试(){}
}
公共类Test1:testwhere T:ITestA{}
公共类Test2:testwhere T:ITestB{}

类型参数上的约束是合取的(AND),因此此处使用的任何类型都必须实现这两个接口

如前所述,一种方法是为两个接口创建一个超级接口,并将您的类型参数约束到该接口(请注意,我添加了常用的接口前缀
I
):

现在,
测试
超类不能从程序集外部继承(它有一个
内部
构造函数)。您的类(
Test1
Test2
)只使用超类的逻辑,每个类都使用一个所需的接口作为约束。客户端代码必须根据他们想要使用的接口约束来选择使用哪一个

此外,如果您的接口中有希望在
测试中使用的通用代码,则应将其提取到超级接口,并使您的超级类受其约束,从而实现两种方法的混合:

public interface IBase { }
public interface ITestA : IBase { }
public interface ITestB : IBase { }
public abstract class Test<T> where T : IBase {
    internal Test() { }
}
public class Test1<T> : Test<T> where T : ITestA { }
public class Test2<T> : Test<T> where T : ITestB { }
公共接口IBase{}
公共接口ITestA:IBase{}
公共接口ITestB:IBase{}
公共抽象类测试,其中T:IBase{
内部测试(){}
}
公共类Test1:testwhere T:ITestA{}
公共类Test2:testwhere T:ITestB{}

您正在约束参数以继承两个接口。约束以继承两个接口都是无用的。您正在约束参数以继承两个接口。约束