我如何乘以浮点数和泛型类型?

时间:2012-02-28 16:43:22

标签: c# generics mono

我正在使用C#在OS X上使用Unity 3.4.2进行编程。

我有一个如下课程:

class Foo<T>
{
    public T DoFoo(T bar)
    {
        float aFloatValue = 1.0f;
        // Do other stuff...
        return aFloatValue * bar;
    }
}

当Unity编译这个类时,它会给我这个错误信息:

  

错误CS0019:运算符*' cannot be applied to operands of type 浮点数'和'T'

我知道我为T提供的类型将支持乘法浮点数。在这种情况下,如何实现泛型乘法?

5 个答案:

答案 0 :(得分:9)

啊,好吧,'哈斯克尔。

你不能在C#中做到这一点,你应该有多个DoFoo,一个用于float,一个用于double,一个用于十进制 - 没有那么多浮点类型。您也可以删除float变量,因为无论如何它都会隐式地转换为double。

答案 1 :(得分:6)

单独使用泛型不可能这样做,因为它们不支持+, /, -, *等运算符。要做到这一点,你需要以接口或lambda的形式引入一个抽象层来提供操作。

例如

class Foo<T> {
  Func<T, float, T> _multiplyFunc;
  public Foo(Func<T, float, T> multiplyFunc) {
    _multiplyFunc = multiplyFunc;
  }
  public T DoFoo(T bar) {
    float aFloatValue = 1.0f;
    return _multiplyFunc(bar, aFloatValue);
  }
}

现在在Foo<T>的施工时间你可以告诉它如何乘以float类型

var f = new Foo<MyType>((x, y) => x * y);

答案 2 :(得分:5)

在C#4中,如果您对dynamic有信心,可以使用float * T => T

class Foo<T>
{
    public T DoFoo(T bar)
    {
        dynamic aFloatValue = 1.0f;
        // Do other stuff...
        return aFloatValue * bar;
    }
}

其他选项包括:

  1. 使用表达式树并将其编译为委托(适用于缓存),为您进行乘法运算。
  2. 反思 - 直接或首先制作代表。
  3. 接受代表,正如JaredPar提到的那样。

答案 3 :(得分:3)

因为您说dynamic不是一个选项:如果您获得MiscUtil,我在那里为泛型运营商写了一些支持。请特别注意Operator.MultiplyOperator.MultiplyAlternative,讨论here。这会在运行时解析方法,根据需要将它们烘焙到委托中。

这使用Expression API,因此可以在3.5上使用,但如果需要,我可以使用ILGenerator

重现2.0

答案 4 :(得分:2)

试试这个

class Foo<T>
{
    public T DoFoo(T bar)
    {
        float aFloatValue = 1.0f;
        var barValue = bar as dynamic;
        return aFloatValue * bar;
    }
}

它应该工作,没有遇到任何错误......