Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#:在同一个泛型变量上是否可能有多个泛型约束?_C#_Generics - Fatal编程技术网

C#:在同一个泛型变量上是否可能有多个泛型约束?

C#:在同一个泛型变量上是否可能有多个泛型约束?,c#,generics,C#,Generics,用一个例子来说明这一点: ??? public class Foo<T> where T:(ClassA || ClassB){} ???公共类Foo其中T:(ClassA | | ClassB){} 是否可以对or关系中的许多不相关的类限制T(T是ClassA或ClassB,但不是别的),或者实现这一点的唯一方法是 使ClassA和ClassB都实现相同的接口 使两个类都派生自同一基类 并将其用作约束条件 因此,为了澄清问题:我的问题并不关心是否可以为n个变量设置n

用一个例子来说明这一点:

    ??? public class Foo<T> where T:(ClassA || ClassB){}
???公共类Foo其中T:(ClassA | | ClassB){}
是否可以对or关系中的许多不相关的类限制T(T是ClassA或ClassB,但不是别的),或者实现这一点的唯一方法是

  • 使ClassA和ClassB都实现相同的接口
  • 使两个类都派生自同一基类
并将其用作约束条件


因此,为了澄清问题:我的问题并不关心是否可以为n个变量设置n个通用约束,我想知道是否可以为同一个变量设置n个约束。

不,如果你仔细想想,它不会很有用

应用泛型约束的目的是确保代码能够对类型执行某些操作。例如,
new()
约束确保您可以执行
new T()
,这对于无约束类型是不可能的。但是应用“或”约束并不能为
T
提供任何有用的静态保证,因此您不能真正将其用于任何事情


但是,对于单个类型的变量,您可以有多个约束,但它们是“和”约束,即它们都必须满足。

简短的回答是:,您不能。其他人已经解释了原因,但简而言之,您将失去泛型附带的类型安全性


如果出于任何原因您仍然需要它,那么有一个解决方案可以使用方法重载,而编译器将完成其余的工作

public void Foo<T>(T instance) where T : ClassA
{
   GenericFoo(instance);
}

public void Foo<T>(T instance) where T : ClassB
{
    GenericFoo(instance);
}

private void GenericFoo(object instance)
{
  // Do stuff
}
公共void Foo(T实例),其中T:ClassA
{
GenericFoo(实例);
}
公共void Foo(T实例),其中T:ClassB
{
GenericFoo(实例);
}
私有void GenericFoo(对象实例)
{
//做事
}
我将为两者实现不同类型的逻辑,并返回适当的。当然,这可以通过使用接口来完成

即使您可以保证这两种类型具有完全相同的成员,编译器也无法验证这一点


通过让两个类实现相同的接口,您可以向编译器保证它们至少共享接口的成员,并且这些成员可供泛型类使用。这就是接口存在的原因,也是泛型的全部要点。

如果我理解正确,您基本上希望将表达式作为约束的一部分进行求值,据我所知,这是不可能的

但类型参数可以有多个约束,只是不能作为表达式。请参见以下内容:

class EmployeeList,其中T:Employee,ieemployee,System.IComparable,new()
{
// ...
}
这里
T
sure有多个约束,但不是作为表达式


在这种情况下,您可能希望查看一下您的设计,以消除您的问题

没有或者,您所能做的就是对基类或接口进行约束。如果可能,您将如何处理不在ClassB中的ClassA.Foo?当成员名称相同但类型不同时会发生什么?@markbenningfield:这个问题是关于约束两个不同的类型参数。这是一个关于对一个类型参数应用两个约束的问题。请参见此问题的答案@BoltClock:我已经撤销了该标志,但我知道我以前看到过这个问题。@HenkHolterman:我的问题本质上是理论性的,尽管我可以想象这样的情况:我的类可以处理返回相同结果的两个不相关的类。我将为两者实现不同类型的逻辑,并返回适当的。当然,这可以通过接口来实现。我知道,我只是出于好奇问:)为什么建议使用编译时类型安全方法来调用
对象
重载?只需完全删除这些泛型,因为
对象
是私有的,现在我可以保证该对象是
ClassA
ClassB
,正如OP所要求的那样。我不会这样做,我只是回答了这个问题。“使用方法重载,编译器完成其余的工作”编译器在这里除了编译代码之外什么都不做…它确实根据类型约束选择了正确的方法签名,因此在代码
Foo(new ClassA())
Foo(new ClassB())
可以工作,但是
Foo(new ClassC())
不会编译,这正是OP所要求的。请注意,在问题中,Foo是一个类,而不是一个方法,因此需要注意将泛型从一个类移动到另一个方法。
class EmployeeList<T> where T : Employee, IEmployee, System.IComparable<T>, new()
{
    // ...
}