【问题标题】:pass a generic type to a method [duplicate]将泛型类型传递给方法[重复]
【发布时间】:2016-03-23 11:17:09
【问题描述】:

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

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

但是这给了我错误

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

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

那么我该怎么做呢?

【问题讨论】:

  • 试试((dynamic)GL).Uniform1(loc, value);
  • @YacoubMassad:这给了我错误:error CS0119: 'GL' is a type, which is not valid in the given context。我猜 GL 不是命名空间而是静态类。
  • 试试GL.Uniform1(loc,(double)(object)value)
  • 请提供GL.Uniform1的所有重载
  • @esiprogrammer:值不一定是双倍的。

标签: c# generics


【解决方案1】:

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

您可以使用 dynamic 关键字获得与 C++ 模板类似的结果:

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

这会将重载决议推迟到运行时,此时value 的类型实际上是已知的。
但是,如果没有GL.Uniform1 类型为value 的重载,它会抛出异常。
不过,我已经使用过这种确切的方法几次。当您可以确定您将只收到特定的一组类型并且对所有这些类型都有重载时,这是有意义的。
避免运行时异常的另一种解决方案是提供采用object 并执行默认操作的重载。

【讨论】:

  • dynamic 关键字有风险,可能导致运行时错误。如果传入的不是GL.Uniform1 接受的类型,它将抛出。
  • @DavidPine:是的,这就是为什么我解释了代码下面的陷阱。
  • 您能否扩展“避免运行时异常的另一种解决方案是提供采用对象并执行默认操作的重载。”?
  • @gartenriese 我的意思是要有一个GL.Uniform1(int, object)
  • 反对者,如果您不发表评论,我将无法改进我的答案。请留下您的反馈,谢谢。
【解决方案2】:

也许您应该传递一个双精度值,因为这是您的函数所需要的。

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

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


C# 没有numeric generic type constraint

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

但是,由于 float 和 int 都可以在不损失精度的情况下转换为双精度,因此您可能只使用一个函数(采用双精度)。

  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

【讨论】:

  • 不,GL.Uniform1 也可以采用浮点数或整数,而不仅仅是双精度数。如果它只需要一个双精度,我就不需要通用方法。
  • @gartenriese 我不确定您是否真的需要通用方法。您可能会对您的 C++ 背景及其模板产生偏见。你是怎么打电话给setUniform1的?您传递的值来自哪里?
  • @DanielHilgarth:我想用 int、float 或 double 调用 setUniform1。还有一个setUniform2,它将采用其他类型并调用GL.Uniform2。我认为它可以让我免于复制和粘贴每种类型的所有方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-07
  • 1970-01-01
相关资源
最近更新 更多