C# 将泛型类型传递给方法

C# 将泛型类型传递给方法,c#,generics,C#,Generics,我想编写一个泛型函数,将泛型参数传递给具有多个重载的函数。C++等价的是。以下是我尝试过的: public void setUniform1<T>(int loc, T value) { GL.Uniform1(loc, value); } public void setUniform1(int loc,T值){ 总帐统一金额1(loc,价值); } 然而,这给了我一个错误 错误CS1503:参数2:无法从“T”转换为“double” GL.Uniform1值参数有几种类

我想编写一个泛型函数,将泛型参数传递给具有多个重载的函数。C++等价的是。以下是我尝试过的:

public void setUniform1<T>(int loc, T value) {
    GL.Uniform1(loc, value);
}
public void setUniform1(int loc,T值){
总帐统一金额1(loc,价值);
}
然而,这给了我一个错误

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

GL.Uniform1
值参数有几种类型,我猜double是第一个重载,这就是它试图转换为double的原因


那么我该怎么做呢?

C++模板和.NET泛型看起来一样,但行为不同:.NET泛型需要在编译时完全可解析。在你的例子中,这是不可能的

可以实现与C++模板的类似结果,使用<代码>动态< /COD>关键字:

public void setUniform1<T>(int loc, T value) {
    GL.Uniform1(loc, (dynamic)value);
}
public void setUniform1(int loc,T值){
总帐统一货币1(loc,(动态)值);
}
这将把重载解析推迟到运行时,此时
值的类型实际上是已知的。
但是,这有一个问题,即如果
值的类型没有重载
GL.Uniform1
,它将抛出异常
尽管如此,我已经多次使用这种方法。当您可以确定只会收到一组特定的类型并且所有类型都有重载时,这是有意义的。

避免运行时异常的另一个解决方案是提供一个重载,该重载接受
对象并执行默认操作。

也许您应该传递一个double,因为这是您的函数所需要的

  public void setUniform1(int loc, double value) 
  {
      GL.Uniform1(loc, value);
  }
泛型类型仅在您不需要特定数据类型时有用,但在本例中您需要


C#没有一个

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

然而,由于float和int都可以转换为double而不损失精度,因此您可能只需要一个函数(使用double)


请参阅。

尝试
((动态)GL).Uniform1(位置,值)
@YacoubMassad:这给了我一个错误:
错误CS0119:“GL”是一个类型,在给定上下文中无效
。我猜GL不是一个名称空间,而是一个静态类。请尝试
GL.Uniform1(loc,(double)(object)value)
请提供
GL.Uniform1
@esicprogrammer:value不一定是双精度的。
dynamic
关键字有风险,可能导致运行时错误。如果传入的不是
GL.Uniform1
接受的类型,它将抛出。@DavidPine:是的,这就是为什么我解释了代码下面的陷阱。您是否可以扩展到“避免运行时异常的另一个解决方案是提供一个重载,该重载接受对象并执行默认操作。”?@gartenriese我的意思是有一个
GL.Uniform1(int,object)
Downvoter,如果你不留下评论,我无法改进我的答案。请留下您的反馈,谢谢。不,GL.Uniform1还可以接受浮点或整数,而不仅仅是双精度。如果只需要一个double,我就不需要泛型方法。@gartenriese我不确定您是否真的需要泛型方法。您可能会被C++背景和模板所偏袒。您实际上是如何调用
setUniform1
?传递的值来自哪里?@DanielHilgarth:我想用int、float或double调用
setUniform1
。还有一个
setUniform2
,它将采用其他类型并调用GL.Uniform2。我认为它可以避免复制和粘贴每种类型的所有方法。
  int    i;
  float  f;
  double d;

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