【问题标题】:Overload with generic type parameter instead?改用泛型类型参数重载?
【发布时间】:2009-12-08 19:45:58
【问题描述】:

我想添加一个泛型类型方法DoSomething<T>,但为了向后兼容,我希望它简单地从具有相同名称的现有方法中传递泛型类型的类型参数。

public void DoSomething<T>(Data data)
{
    //do something with Data, it depends on the type of T
}

public void DoSomething(Data data, Type dataType)
{
    DoSomething<dataType>(group);
}

但是,新的 DoSomething 中的 &lt;dataType&gt; 会引发以下类型检查错误:“需要类型名称或命名空间。”

有人可以帮助我理解我的思维差距导致上述示例成为类型检查错误吗?我正在做的只是……糟糕的设计吗?

【问题讨论】:

  • dataType 仍然是 Type 对象的实例...不是可以用来声明新的泛型对象的类型定义。您需要使用反射调用方法的通用版本。
  • 实际上,这不起作用还有第二个原因。您正在尝试从静态方法调用实例方法。
  • @Max:谢谢,我更新了我的示例,使其与我更感兴趣的问题正确相关。

标签: c# generics parameters overloading


【解决方案1】:

泛型是关于在编译时知道类型 - 你只在执行时知道类型。

有两种方法可以解决这个问题:

  • 让通用代码改为调用非通用代码。这很容易,但您不会享受泛型的任何好处。

  • 使用反射从非泛型代码中调用泛型代码。这很繁琐,性能也不佳,但您可以弃用非泛型代码并最终将其删除。

或者你现在可以删除它,然后修复所有内容:)

【讨论】:

  • 如果真的有问题;使用一些编译的 lambda 表达式,你也可以很快地得到这个:-)
  • 当我尝试编写看起来像 Mike Atlas 的示例的代码时,泛型在编译时连接的事实是我所缺少的。
【解决方案2】:

我通常发现反转方法之间的关系更容易,即:

private void DoSomething<T>(Data data)
{
    DoSomething(data, typeof(T));
}

private void DoSomething(Data data, Type dataType)
{
    ...
}

【讨论】:

  • 是的,这是你必须要做的。
【解决方案3】:

这里的问题是您混合了通用参数和运行时类型信息。用于泛型参数的类型值必须在编译时建立并嵌入元数据中。 Type 类型是一个构造,其值在编译时未知。因此 2 不兼容。

您最好的选择是将原来的 DoSomething 方法作为主要方法,并将新的通用方法输入其中。

static void DoSomething<T>(Data data) {
  DoSomething(data, typeof(T));
}

static void DoSomething(Data data, Type dataType) {
  ...
}

【讨论】:

    【解决方案4】:

    如果这是一个私有方法,那么外部向后兼容性有什么问题?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2010-11-22
      • 2020-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-01
      相关资源
      最近更新 更多