【问题标题】:How to deal with known generic type without boxing/unboxing如何在没有装箱/拆箱的情况下处理已知的泛型类型
【发布时间】:2022-11-03 18:41:00
【问题描述】:

我有一个处理大量数据的通用方法。

当数据是特定类型(在这种情况下为double)时,我想应用一些额外的处理。

有没有比下面示例中所示的(非常慢的)装箱/拆箱更好的方法?

这似乎意味着我们需要让编译器相信Tdouble 是同一类型,在断言这一点的if..else 部分中。

public static T[] HalfIfDouble<T>(T[] data)
{
    T[] result;

    if (typeof(T) == typeof(double))
    {
        // result = data.Select(x => x * 0.5).ToArray(); // does not compile

        result = data.Select(x =>
        {
            double d = (double)(object)x;
            return (T)(object)(d * 0.5);
        }).ToArray();
    }
    else
    {
        result = data;
    }

    // do some more processing...

    return result;
}

真正的功能显然比这个例子更复杂。

需要在 .NET Framework 和 .NET 6 中工作。

【问题讨论】:

  • 为什么不能投射整个数组?即if( typeof(T) == typeof(Double) ) { return (Double[])data;}`?

标签: c# generics


【解决方案1】:

这种最简单的方法是专门为double[] 重载该方法:

public static T[] HalfIfDouble<T>(T[] data)
{
    return data;
}

public static double[] HalfIfDouble(double[] data)
{
    return data.Select(x => x * 0.5).ToArray();
}

Working example

【讨论】:

  • 这很好,但是您需要演示HalfIfDouble&lt;T&gt;(T[]) 如何在适当的时候正确调用HalfIfDouble(Double[])。当涉及泛型时,您不能依赖重载选择:例如如果 ``HalfIfDouble<T>(T[])` 从其他泛型方法,并且该方法有一个带有&lt;Double&gt; 的调用站点,那么这里的非泛型方法将不会被调用。
  • @Dai 没有。当参数为double[] 时,将解决正确的重载。
  • “当参数为double[] 时,将解决正确的重载。”- 该方法仅在您控制所有调用站点的重载解决方案时才有效 - 在很多情况下这不起作用,例如如果从调用泛型方法其他泛型方法,或者如果您的程序集被您无法控制的另一个程序集使用(或将回调传递给)另一个程序集,该程序集将调用泛型方法。
猜你喜欢
  • 1970-01-01
  • 2016-11-23
  • 1970-01-01
  • 1970-01-01
  • 2012-10-27
  • 1970-01-01
  • 1970-01-01
  • 2021-12-09
  • 1970-01-01
相关资源
最近更新 更多