【问题标题】:C# - how to apply different generic methods for T and T[]C# - 如何为 T 和 T[] 应用不同的泛型方法
【发布时间】:2010-12-16 23:24:57
【问题描述】:

我有大量不同内置类型的对象,例如int、bool[]、double[] 等

在对象 M 上,我想对集合的每个元素执行一次 MyMethod 操作。但是,我需要对数组执行不同的操作,对单个值执行不同的操作。

首先,我尝试了:

public void MyMethod<T>(T value)

public void MyMethod<T>(T[] array)

但是,第一种方法适用于集合的每个元素,包括数组。

我的下一个尝试是:

public void MyMethod<T>(T value) where T : struct

public void MyMethod<T>(T[] array)

当我尝试调用该方法时,它产生了以下效果:

错误 8 类型“T”必须是不可为空的值类型,才能在泛型类型或方法“MyMethod(T)”中用作参数“T”

编译器似乎没有看到 MyMethod(T[] array) 方法。 我哪里错了?

最后我提供了一个辅助方法:

public void MyAux<T>(T value) {
    if (value.GetType().IsArray) {
        this.MyMethodForArray(value);
    }
    else {
        this.MyMethodForSingleValue(value);
    }

然后我得到一个错误:

错误 8 方法的类型参数 'MyMethodForArray(T[])' 不能 从用法推断。尝试 指定类型参数 明确的。

如何优雅地处理这个问题?

【问题讨论】:

  • 我只是尝试复制相同但函数被正确调用(即传递数组的数组通用方法和非数组参数的常规版本。)
  • 您的第一种方法应该可以正常工作
  • 试试 MyMethod(IEnumerable 数组)
  • 我没有告诉你我希望从调用中推断出类型 T。
  • 我遍历将其元素作为对象类型实例处理的集合,并将它们传递给 MyMethod 调用。也许像第一个和第二个这样的方法不会成功。

标签: c# generics


【解决方案1】:

如果您这样做时会感到疼痛,请不要这样做。您会注意到框架中的 List 数据类型有一个 Add 和一个 AddRange 方法。一个接受一个项目的方法和一个接受一个项目集合的方法在逻辑上是不同的,所以给它们起不同的名字是有意义的。与其将头撞到类型系统上,不如更改其中一个的名称。

【讨论】:

    【解决方案2】:

    如下创建一个简单的程序

    class Program
    {
        static void Main(string[] args)
        {
            Foo t = new Foo();
            // Line numbering for convenience
            t.MyMethod<bool>(true);                     // #1
            t.MyMethod<bool>(new bool[] { true });      // #2
            t.MyMethod<bool[]>(new bool[] { true });    // #3
        }
    }
    
    public class Foo
    {
        public void MyMethod<T>(T value)
        {
            Console.WriteLine("Single element method called");
        }
    
        public void MyMethod<T>(T[] array)
        {
            Console.WriteLine("Array method called");
        }
    }
    

    输出将是:

    Single element method called
    Array method called
    Single element method called
    

    我怀疑您在第 3 行中调用了该方法,而您计划在第 2 行中调用它。请注意,区别在于另外两个方括号。

    【讨论】:

      【解决方案3】:

      您的函数只有一个版本(数组版本),但使用 params 关键字声明它,如下所示:

      public void MyMethod<T>(params T[] array)
      

      您可能会探索的其他内容是使用 IEnumerable&lt;T&gt; 而不是 T[]

      【讨论】:

      • 据我所知,OP 想要对数组做不同的事情。通过您的方法,通过输入大小为 1 的数组的方法调用和使用一个简单输入的方法调用有什么区别?
      • @Saeed - 起初我是这么想的,但我越是关注这个问题,它看起来就越不明显,而且看起来他只是想提供一种更简单的方法来调用他的函数序列。
      • @Saeed,乔尔的回答假设“不同的东西”正在遍历数组。处理元素没有区别。如果“不同的东西”是显着不同的东西,那么这个答案显然行不通。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多