代码之家  ›  专栏  ›  技术社区  ›  Marcin Tarsier

如何检测泛型类型参数是否为浮点类型?

  •  1
  • Marcin Tarsier  · 技术社区  · 3 年前

    我有一个通用方法,它串行化一些数字配置条目。此外,仅对于浮点类型,它必须同时存储区域性信息。如何判断模板参数为浮点类型?

    以下是我尝试过的:

        public void Bar<T>() where T : System.Numerics.INumber<T> {
            T aa = default(T);
            
            // this is ugly
            if (aa is float || aa is double)
            {
            }
            
            // error: The type 'T' cannot be used as type parameter 'TSelf' in the generic type
            // or method 'IFloatingPoint<TSelf>'. There is no boxing conversion or type parameter
            // conversion from 'T' to 'System.Numerics.IFloatingPoint<T>'.
            if (aa is IFloatingPoint<T>)
            {
            }
            
            // works fine and IFloatingPoint<T> would also work if T was constrained to
            // IFloatingPoint<T> (but I need to accept also integer types)
            if (aa is INumber<T>)
            {
            }
            
    
        }
    

    我能换个说法吗 aa is IFloatingPoint<T> 表达式(或使用类似的东西)使其工作并优雅地检查 T 反对像浮点一样?类似于C++

    if constexpr (std::is_floating_point_v<T>) {
    }
    
    2 回复  |  直到 3 年前
        1
  •  3
  •   Sweeper    3 年前

    如果你真的想检查 IFloatingPoint<T> 合规性,您可以检查:

    typeof(T).GetInterface("IFloatingPoint`1") != null
    

    但检查确实没有错 double 和 float 单独使用,如果这是您正在使用的仅有的两种类型。您不需要默认值。就这么做吧

    typeof(T) == typeof(double) || typeof(T) == typeof(float)
    
        2
  •  2
  •   DavidG    3 年前

    作为Sweeper提供的答案的替代方案,并且由于您提到 is_floating_point 函数,您可以像这样复制该功能:

    public bool IsFloatingPoint<T>()
    {
        return typeof(T)
            .GetInterfaces()
            .Any(i => i.IsGenericType &&
                      i.GetGenericTypeDefinition() == typeof(IFloatingPoint<>));
    }
    

    现在在你的 Bar 方法

    public void Bar<T>() 
        where T : System.Numerics.INumber<T>
    {
        if (IsFloatingPoint<T>())
        {
            // Do the floating point stuff
        }
    }