【问题标题】:Generic numeric type通用数字类型
【发布时间】:2015-07-15 17:14:05
【问题描述】:

我有一个接受参数T 的扩展方法。该参数为数值类型,为以下之一:byte、short、int、long。

我需要检查T 是否等于0。怎么可能呢?

public static void WriteFlaggedValue<T>(this OutPacket outPacket, uint flag, T value, ref uint outputFlag) where T : struct,
      IComparable,
      IComparable<T>,
      IConvertible,
      IEquatable<T>,
      IFormattable
    {
        if (value == 0)
        {

        }

    }

【问题讨论】:

  • 看来你会想要this检查。
  • 我认为没有任何内置支持可以强制 T 为数字,这可能是个坏主意。但你不能只做if(value ==(T)0)吗?如果您只有 4 种可能的类型,我可能会建议只为每种类型进行重载。
  • 你应该如何强制 Tbyte, short, int and long?泛型似乎不是正确的方法。也许超载更适合
  • 您可以使用 typeof() 并检查它的数字类型。如果不是你想要的,则抛出异常。
  • @tdbeckett 虽然这是真的,但与 4 次重载相比,我仍然认为这种方法相当草率。使用该方法,您最终会遇到运行时错误而不是编译时错误。

标签: c#


【解决方案1】:

你可以像这样使用EqualityComparer

if(EqualityComparer<T>.Default.Equals(value, default(T))
{
}

堆栈溢出:EqualityComparer<T>.Default vs. T.Equals

MSDN:EqualityComparer.Default

【讨论】:

    【解决方案2】:

    您必须这样做的一个选项是使用IComparable 接口的compareTo 方法和default type value...

    如果它们相等,它将返回零作为is specified here

    条件如下所示:

    if (value.CompareTo(default(T)) == 0)
    

    在你的方法中使用:

    public static void WriteFlaggedValue<T>(this OutPacket outPacket, uint flag, T value, ref uint outputFlag) where T : struct,
          IComparable,
          IComparable<T>,
          IConvertible,
          IEquatable<T>,
          IFormattable
        {
            if (value.CompareTo(default(T)) == 0)
            {
    
            }
    
        }
    

    如果值可以是null,那么你必须处理它。

    【讨论】:

      【解决方案3】:

      怎么样:

      private T _minimumValue = default(T)
      
      public bool IsEqualsZero(T value) 
      {
          return (value.CompareTo(_minimumValue) == 0);
      }
      

      正如This Answer中所建议的那样

      【讨论】:

        【解决方案4】:

        既然还没有人说过,为什么不简单地利用IEquatable&lt;T&gt; 界面免费提供的非常直接的Equals(T other) 功能:

        if (value.Equals(default(T)))
        {
            // ...
        }
        

        关于 default 关键字的使用说明,以防 OP 想知道它是如何工作的:

        找到here 的文档如下(强调我的):

        解决方法是使用默认关键字,对于引用类型返回 null,对于数值类型返回零


        还应该提到的是,仅仅因为您将T 限制为struct,并不意味着您可以保证T 始终是数字。例如,您的方法可以接受 DateTime 作为泛型类型。或许您已经知道这一点并且可以接受。

        在此处了解更多信息:What is the “base class” for C# numeric value types?

        【讨论】:

          猜你喜欢
          • 2023-03-30
          • 1970-01-01
          • 1970-01-01
          • 2013-01-04
          • 2010-11-21
          • 2012-04-06
          • 2022-01-03
          相关资源
          最近更新 更多