将泛型类型传递给方法

时间:2016-03-23 11:17:09

标签: c# generics

我想编写一个泛型函数,将泛型参数传递给具有多个重载的函数。 C ++等价物将是http://go.microsoft.com/fwlink/?LinkID=392859。这是我试过的:

public void setUniform1<T>(int loc, T value) {
    GL.Uniform1(loc, value);
}

然而这给了我错误

  

错误CS1503:参数2:无法从'T'转换为'double'

GL.Uniform1为值参数提供了几种类型,我猜双重是第一次重载,这就是它尝试转换为double的原因。

那我该怎么做?

2 个答案:

答案 0 :(得分:2)

C ++模板和.NET泛型只是看起来相同,但表现不同:.NET泛型需要在编译时完全可解析。在您的示例中,这是不可能的。

使用dynamic关键字

可以获得与C ++模板类似的结果
public void setUniform1<T>(int loc, T value) {
    GL.Uniform1(loc, (dynamic)value);
}

这会将重载决议推迟到运行时,此时value的类型实际上是已知的 但是,如果GL.Uniform1的类型没有value的重载,则会出现异常的问题。
不过,我已经多次使用过这种方法。当你可以确定你只会收到某种类型并且所有类型都有重载时,这是有道理的 避免运行时异常的另一个解决方案是提供一个需要object并执行默认操作的重载。

答案 1 :(得分:1)

也许你应该传递一个双倍,因为那是你的功能所需要的。

  public void setUniform1(int loc, double value) 
  {
      GL.Uniform1(loc, value);
  }

通用类型仅在您不需要特定数据类型时才有用,但在这种情况下,您可以使用。

C#没有numeric generic type constraint

鉴于GL.Uniform有多个版本,每个版本都采用特定的数据类型,通常需要三个版本的函数。

但是,因为float和int都可以转换为double而不会损失精度,所以你可能只使用一个函数(取一个double)就可以了。

  int    i;
  float  f;
  double d;

  setUniform1(loc, i);   // implicit conversion int   => double
  setUniform1(loc, f);   // implicit conversion float => double
  setUniform1(loc, d);

请参阅Implicit Numeric Conversions