【问题标题】:Can I extend a generic class putting a restriction on the types that can be used?我可以扩展一个泛型类来限制可以使用的类型吗?
【发布时间】:2012-03-24 16:23:29
【问题描述】:

我想扩展 IEnumerable 类,但仅限于可操作的类型(int、decimal、single 和 double)。

这可行吗?我没有看到限制这个的方法:

public static class IEnumerableExtension
{
    public static decimal FindBestSubsequence<T> (this IEnumerable<T> source, out int startIndex, out int endIndex)
    {

    }
}

提前致谢。

【问题讨论】:

  • 你可能想看看 'where T : struct' 只是一个想法。
  • @BrokenGlass:除了 Comparable 之外,我真的需要更多的东西,所以它不是一个重复的恕我直言。
  • 该问题的其他答案中的建议几乎相同

标签: c# .net generics extension-methods


【解决方案1】:

您正在寻找generic constraints,但您不能将类型参数限制为仅对特定类型集有效。你最接近的可能是这样的:

public static decimal FindBestSubsequence<T>
    (this IEnumerable<T> source, out int startIndex, out int endIndex)    
     where T : struct, IConvertible, IFormattable, IComparable<T>, IEquatable<T>,
     IComparable

... 因为这些都是这些类型中的每一个都实现的接口。但是,这不会阻止 Int16 被用作类型参数。您肯定不希望它适用于IEnumerable&lt;short&gt;?如果用于此会有什么问题?

可以拥有一组非泛型公共重载,然后调用受约束的泛型 private 方法:

public static decimal FindBestSubsequence(this IEnumerable<decimal> source,
    out int startIndex, out int endIndex)
{
    return FindBestSubsequenceImpl(source, startIndex, endIndex);
}

public static decimal FindBestSubsequence(this IEnumerable<int> source,
    out int startIndex, out int endIndex)
{
    return FindBestSubsequenceImpl(source, startIndex, endIndex);
}

// etc

// Could constrain T more if it was useful in the method, but we know
// T will only be one of the types we want, because only this class can
// call this method
private static decimal FindBestSubsequence<T>
    (IEnumerable<T> source, out int startIndex, out int endIndex)    
     where T : struct
{
}

【讨论】:

  • 谢谢乔恩。我正在编写的算法适用于任何数字类型,并且可能实现所有这些接口的结构是数字的。
  • @SoMoS:不一定。例如,DateTime 会计数。那会是个问题吗?其实如果只将T约束到实现方法需要的接口(可能是IComparable&lt;T&gt;),你在考虑什么问题?
  • 好吧,它将在 DateTime 上执行,但结果没有任何意义。也许我可以在运行时检查类型并抛出一些东西。
  • @SoMoS:这肯定没有意义吗?如果您可以描述您正在实施的内容,那将会有所帮助。您是否看到我为其他替代方案编辑的答案?
  • @JonSkeet:我正在搜索一系列数字,找到在添加其值时给出最大值的子序列(它们是 + 和 - 数字)。因此,对无符号值执行该方法是没有意义的。
【解决方案2】:

您可以使用 where T : struct 限制值类型

来自MSDN

其中 T: 结构

类型参数必须是值类型。除 Nullable 之外的任何值类型 可以指定。请参阅使用可空类型(C# 编程指南)了解 更多信息。

【讨论】:

    猜你喜欢
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    相关资源
    最近更新 更多