繁体   English   中英

Generics 的 C#/修复运算符

[英]C#/Fixing Operators for Generics

我尝试在 Generics 上应用运算符(例如,乘法)

    public static List<TOutput> Conversion<TOutput>(List<TInput> input)
    {
        List<TOutput> outList = new List<TOutput>();
        foreach(TInput tinput in input)
        {
            double dbl = tinput *tinput;
            outList.Add(dbl);

        }
        return outList;

    }

修复它的任何解决方法?

如果没有反映出类型,就不可能。 有一些代码可以作为MiscUtil的一部分提供

这现在可以在 C# 11 / .NET 7(或以上):

public static List<TOutput> Conversion<TInput, TOutput>(List<TInput> input)
    where TInput : IMultiplyOperators<TInput, TInput, TOutput>
{
    List<TOutput> outList = new List<TOutput>();
    foreach (TInput tinput in input)
    {
        TOutput product = tinput * tinput;
        outList.Add(product);

    }
    return outList;
}

编译器不应允许您将double赋值为未知类型:

outList.Add(DBL);

尽管如此,您可能会尝试将dbl分配给一种FluxCapacitor。 您的代码正在尝试完成两个不兼容的事情:返回通用(未知)类型的列表,以及2)强制该类型为double。 这没有意义,这就是你遇到困难的原因。 您可以使用反射(如Porges指出的优秀链接)动态解决这个问题,但您确实需要问自己:为什么要尝试将浮点数分配给具有未知类型的类? 调用代码可能要求List<bool>的结果。 尝试分配会有多大意义

double foo = 1.5;
bool bar = foo;

零。 您可以让编译器执行任何足够的翻筋斗,但是您需要重新评估例程的目的,为什么要尝试将特定数据类型放入通用数据类型,以及此例程是否需要返回通用列表。

“MiscUtil”答案(已被接受)将是我的第一选择;-p

您也可以在调用者处考虑LINQ:

var prodList = originalList.Select(x=>x*x).ToList();

由于调用者知道类型(假设它本身不是通用的,这应该可行。

为了完整起见,这里的另一个选项(在4.0中)是dynamic

public static List<TOutput> Conversion<TOutput>(List<TInput> input)
{
    List<TOutput> outList = new List<TOutput>();
    foreach(TInput tinput in input)
    {
        TOutput square = (dynamic)tinput * (dynamic)tinput;
        outList.Add(square);

    }
    return outList;
}

您可以使用缓存的lambda进行计算(和/或转换)。

这不需要DLR或动态关键字,因此它在C#3.0中完全可用

static class Squarer<T>
{
    private static readonly Func<T, T> _square;
    static Squarer()
    {
        ParameterExpression x = Expression.Parameter(typeof(T), "x");
        _square = Expression.Lambda<Func<T, T>>(
            Expression.Multiply(x, x),
            x).Compile();
    }

    public static T Square(T value)
    {
        return _square.Invoke(value);
    }
}

Console.WriteLine(Squarer<double>.Square(1234.5678));
Console.WriteLine(Squarer<decimal>.Square(1234.5678m));
Console.WriteLine(Squarer<int>.Square(1234));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM