C# C-如何对T和T应用不同的通用方法[]

C# C-如何对T和T应用不同的通用方法[],c#,generics,C#,Generics,我收集了大量不同内置类型的对象,例如int、bool[]和double[]等 在对象M上,我希望对集合的每个元素执行一次操作MyMethod。但是,我需要对数组执行不同的操作,对单个值执行不同的操作 首先,我试着: public void MyMethod<T>(T value) public void MyMethod<T>(T[] array) 但是,第一种方法应用于集合的每个元素,包括数组 我的下一次尝试是: public void MyMethod<T&

我收集了大量不同内置类型的对象,例如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”必须是不可为null的值类型,才能将其用作泛型类型或方法“MyMethodT”中的参数“T”

编译器似乎没有看到MyMethodT[]数组方法。 我错在哪里

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

public void MyAux<T>(T value) {
    if (value.GetType().IsArray) {
        this.MyMethodForArray(value);
    }
    else {
        this.MyMethodForSingleValue(value);
    }
但后来我犯了一个错误:

错误8方法的类型参数无效 “MyMethodForArray[]”不能为空 从用法推断。尝试 指定类型参数 明确地说


如何优雅地管理此问题?

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

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

您可能会探索的另一个方法是使用IEnumerable而不是T[]

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

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

您可能会探索的其他方法是使用IEnumerable而不是T[]

创建一个简单的程序,如下所示

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");
    }
}

我怀疑您在第3行中调用了该方法,您计划在第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");
    }
}

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

如果这样做会受伤,请不要这样做。您会注意到框架中的列表数据类型有一个Add和一个AddRange方法。接受一个项的方法和接受一个项集合的方法在逻辑上是不同的,因此给它们取不同的名称是有意义的。与其把头撞在类型系统上,不如更改其中一个的名称

如果你那样做很痛,不要那样做。您会注意到框架中的列表数据类型有一个Add和一个AddRange方法。接受一个项的方法和接受一个项集合的方法在逻辑上是不同的,因此给它们取不同的名称是有意义的。与其把头撞在类型系统上,不如更改其中一个的名称

我只是尝试复制相同的函数,但是函数被正确调用了。传递数组的数组泛型方法和非数组参数的常规版本。您的第一种方法应该可以很好地工作。MyMethodIEnumerable Arrai没有通知您我希望从调用中推断类型t。我在集合中迭代,将其元素作为对象类型实例传递给MyMethod调用。也许像第一个和第二个这样的方法不可能成功。我只是尝试复制相同的方法,但是函数被正确地调用了。传递数组的数组泛型方法和非数组参数的常规版本。您的第一种方法应该可以很好地工作。MyMethodIEnumerable Arrai没有通知您我希望从调用中推断类型t。我在集合中迭代,将其元素作为对象类型实例传递给MyMethod调用。也许像第一次和第二次这样的方法不可能成功。正如我所理解的,OP希望用数组做不同的事情。按照您的方法,按大小为1的数组输入调用方法和按一个简单输入调用方法有什么区别?@Saeed-起初我认为,但我越看这个问题,它就越不明显,看起来他越想提供一种更简单的方法,用序列调用他的函数。@Saeed,Joel的回答假设不同的东西在数组上迭代。在处理这些元素时不会有任何区别。如果不同的东西是非常不同的东西,那么这个答案显然不起作用。按照您的方法,按大小为1的数组输入调用方法和按一个简单输入调用方法有什么区别?@Saeed-起初我认为,但我越看这个问题,它就越不明显,看起来他越想提供一种更简单的方法,用序列调用他的函数。@Saeed,Joel的回答假设不同的东西在数组上迭代。在处理这些元素时不会有任何区别。如果不同的东西是显著不同的东西,那么这个答案显然不起作用。