【问题标题】:Generic method with many types具有多种类型的通用方法
【发布时间】:2019-02-02 21:52:01
【问题描述】:

如果我想要一个泛型方法有很多泛型类型,例如最多 16 个。

我必须重载该方法 16 次还是有更聪明的方法来做到这一点?

public interface IMyInterface { }

public class MyClass {
    public void MyMethod<T1>() where T1 : IMyInterface { }
    public void MyMethod<T1, T2>() where T1 : IMyInterface where T2 : IMyInterface { }
    public void MyMethod<T1, T2, T3>() where T1 : IMyInterface where T2 : IMyInterface 
                                       where T3 : IMyInterface { }
    public void MyMethod<T1, T2, T3, T4>() where T1 : IMyInterface where T2 : IMyInterface 
                                           where T3 : IMyInterface where T4 : IMyInterface { }
    // All the way to T16...
    // Is there any smarter way of doing this
    // instead of having to write it 16 times?
}

【问题讨论】:

  • 你的方法没有实现吗?
  • 为了简单起见,我没有包含任何实现。而且我认为实施没有任何重要性。
  • 但是你的实现肯定会因每种方法而不同,所以你必须以一种或另一种方式编写它,不是吗?
  • 如果你问这个问题,没有办法概括泛型,所以你必须手动或使用 T4 模板来自动化无聊的过程,但最终结果仍然是多个重载,不同数量的仿制药。您可以在此处看到如何自动化的示例:blog.dreasgrech.com/2013/04/…
  • 如果所有不同的泛型参数都实现同一个接口,哪里需要区分?

标签: c# generics methods overloading


【解决方案1】:

如果您查看Action&lt;T1, T2, ....&gt; 的文档,似乎您需要单独实现所有重载。

这是它的reference source。如您所见,它已按照您的示例完成。

Jon Skeet here 可以找到关于为什么不存在 params 等效项的更详细答案。 它指出:

“就 CLR 而言,基本上 Func&lt;T&gt;Func&lt;T1, T2&gt; 是完全不相关的类型,没有什么比 params 更能指定多个类型参数了。”

【讨论】:

  • there seems to be no necessity to distinguish between the types T1 and T2 这不是一个普遍正确的评估。这对于 OP 的当前代码(无返回类型等)是正确的,但 OP 已经提到为了简单起见,代码示例被大量编辑。可能有理由保留该类型。例如,考虑Tuple&lt;T,U&gt; 与区分T (Item1) 和U (Item2) 相关。如果不跟踪这两种类型,您最终将不得不将 Item1Item2 转换为正确的类型,这是异常和错误处理的雷区。
  • 通过包含 'where T1 : IMyInterface' 我确保该方法仅由实现 IMyInterface 的对象使用 - 接口而不是任何其他对象。这是对该功能的错误使用吗?
  • @Flater 我明白你的意思。这实际上已在第一部分中介绍,尤其是 Jon Skeet 的回答。 Tuple&lt;T,U&gt; 没有强制要求 TU 实现相同的接口。这个约束使它成为我提到的特殊情况。我将编辑我的帖子并尝试更准确
  • @DeadlyCow "这是对该功能的错误使用吗?"不,我不认为这是不正确的。如果所有对象或不同类型都使用此接口,那么一种类型和一种约束就足够了。但这只是我的理论思考。因为我无法(如此快速地)提出需要区分 T1 和 T2 的场景。我其实对这个案例很感兴趣,想看看真正的实现
  • @MongZhu:同样的论点仍然适用于Tuple&lt;T,U&gt; where T : class where U : class(或任何其他标识符,例如objectIFooBaseFoo
猜你喜欢
  • 2016-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-30
相关资源
最近更新 更多