【问题标题】:How to use Math.Abs inside my own generic method? [duplicate]如何在我自己的通用方法中使用 Math.Abs​​? [复制]
【发布时间】:2014-02-28 16:08:09
【问题描述】:

以下代码不能用

编译

...无法将 T 转换为 int bla bla bla

bool IsEqual<T>(this T a, T b, T offset)
{
    a = Math.Abs(a);
    b = Math.Abs(b);
    if (Math.Abs(a - b) < offset)
        return true;
    else
        return false;
}

如何在我自己的泛型方法中使用Math.Abs

【问题讨论】:

  • 你不能。您只需要为Math.Abs 实际支持的类型(或您想要使用的较小的类型子集)提供一组重载和一些非常重复的代码

标签: c#


【解决方案1】:

如果 .Net 有 classinterfaceJava 中的 Number,那么您很可能会放一些东西喜欢

 // Doesn't compile; just the idea
 bool IsEqual<T>(this T a, T b, T offset) 
   where T: Number { // <- T can be any integer or floating point type 
     a = Math.Abs(a);
     ....

不幸的是,.Net不提供这样的接口,所以你必须实现IsEqual重载版本

  bool IsEqual(this Double a, Double b, Double offset) {
    return (Math.Abs(a - b) < offset);
  }

  bool IsEqual(this Single a, Single b, Single offset) {
    return (Math.Abs(a - b) < offset); 
  }

  bool IsEqual(this long a, long b, long offset) {
    return (Math.Abs(a - b) < offset);
  }

  bool IsEqual(this int a, int b, int offset) {
    return (Math.Abs(a - b) < offset);
  }
  ...

【讨论】:

    【解决方案2】:

    你不能。在你的方法中,类型参数T 可以是任何东西,一个字符串,一个类,你可以命名它。

    Math.Abs 仅针对一小组参数类型存在。如果您可以将T 限制在他们身上,那就太好了,但这也是不可能的。

    这意味着如果您需要IsEqual 方法来处理不同类型的T,您将不得不手动为它们编写重载:

    bool IsEquals(int a, int b, int offset) { }
    bool IsEquals(double a, double b, double offset) { }
    // and many more
    

    【讨论】:

    • 这里可以使用扩展方法吗?
    • 你当然可以让它们成为扩展方法,但这并不能解决问题。
    • @TheLastError 问题是,无论您是否使用扩展方法,您都必须将 T 约束到某些东西或 Math.Abs​​(a) 将无法编译,但该约束根本不可能,因为C# 规范不允许这样做。并且约束还必须包括operator - 存在于T
    猜你喜欢
    • 1970-01-01
    • 2012-09-22
    • 1970-01-01
    • 2020-03-24
    • 1970-01-01
    • 2017-01-12
    • 2012-03-13
    • 2023-03-26
    • 1970-01-01
    相关资源
    最近更新 更多