如何使用约束将 T 限制为某些特定值类型?

问题描述 投票:0回答:6

我想使用约束来限制 N 可以采用的可能类型。我希望将 N 限制为整数或小数。

public static Chart PopulateInto<T, N>(List<T> yAxis, List<N> xAxis) where N : int, decimal
{
    // Do stuff here
}

任何帮助表示赞赏...

c# linq generics constraints
6个回答
24
投票

无法将泛型参数限制为特定值类型。

但是,您可以通过添加 struct 来强制其为

a
值类型或
where N : struct
,仅此而已。


14
投票

不幸的是,不可能指定只允许特定值类型的泛型类型约束。更重要的是,即使允许也没有多大意义。

您可以指定一个类作为通用约束,但这是因为您可以从类继承,因此该约束设置了您可以使用的类型的最小阈值。

如果值类型允许这样做,那么您无法从这些类型继承,那么您将有效地将自己限制为只能使用该类型。

因此你不能这样做,但你有一些选择:

  • 您可以在没有约束的情况下声明它,并在运行时处理问题。 我不推荐这种方式
  • 您可以声明采用您感兴趣的特定类型的重载。

    因为你只有两种这样的类型,所以我建议这样做。

以下是您要声明的重载:

public static Chart PopulateInto<T>(List<T> yAxis, List<int> xAxis)
{
    // Do stuff here
}

public static Chart PopulateInto<T>(List<T> yAxis, List<decimal> xAxis)
{
    // Do stuff here
}

现在,此外,如果您对这些值的处理并不真正依赖于这些类型的数字质量,您只是想限制可以处理的类型,那么您也可以随时声明您的原始方法,私下,并从重载中调用此方法。这仍然会限制您的代码仅允许

int
decimal
publicly,但您的实现仍然是通用的。如果不确切知道“在这里做东西”意味着什么,就不可能判断这是否是一个可行的选择,但无论如何,这里是代码:

public static Chart PopulateInto<T>(List<T> yAxis, List<int> xAxis)
{
    return PopulateInto<T, int>(yAxis, xAxis);
}

public static Chart PopulateInto<T>(List<T> yAxis, List<decimal> xAxis)
{
    return PopulateInto<T, decimal>(yAxis, xAxis);
}

private static Chart PopulateInto<T, N>(List<T> yAxis, List<N> xAxis) where N : struct
{
    // Do stuff here
}

10
投票

没有办法在有约束的情况下做到这一点。另一种方法是,假设

PopulateInto
可以与通用 N 一起使用,则使核心算法通用且私有,并提供 2 个公共重载,分别采用
int
decimal
。这会产生类似的效果

public static Chart PopulateInto<T>(
  List<T> yAxis, 
  List<decimal> xAxis) {

  return PopulateIntoCore(yAxis, xAxis);
}

public static Chart PopulateInto<T>(
  List<T> yAxis, 
  List<int> xAxis) {

  return PopulateIntoCore(yAxis, xAxis);
}

private static Chart PopulateIntoCore<T, N>(
  List<T> yAxis, 
  List<N> xAxis) where N : struct {
  ...
}

4
投票

正如 Pieter 所说,您不能使用编译时检查来实现这一点。但是,您可以在运行时执行以下操作:

if(!(typeof(N).equals(typeof(int32))) && !(typeof(N).equals(typeof(decimal))))
  // do something

4
投票

回答标题中的问题,但不回答问题正文。

要涵盖Value Types通常表示的

所有
类型(包括可空值类型,以及
string
,即使它是技术上的引用类型),您需要3个重载:

public void Foo<T>(T arg) where T : struct
public void Foo<T?>(T? arg) where T : struct
public void Foo<string>(string arg)

来自关于通用约束的 MSDN 文档

where T : struct
类型参数必须是不可为 null 的值类型。


2
投票

您可以获得的壁橱是Where T:struct,IComparable,IFormattable,IConvertible。 所有值类型都实现这些接口。

© www.soinside.com 2019 - 2024. All rights reserved.