开发者

C# - how to apply different generic methods for T and T[]

开发者 https://www.devze.com 2023-01-30 17:55 出处:网络
I have a big collection of objects of different built-in types, e.g. int, bool[], double[] etc. On object M I wanted to perform an operation MyMethod once with each element of the collection. However

I have a big collection of objects of different built-in types, e.g. int, bool[], double[] etc.

On object M I wanted to perform an operation MyMethod once with each element of the collection. However, I needed to perform different operation with arrays and different with single values.

Firstly, I tried:

public void MyMethod<T>(T value)

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

but then, the first method 开发者_如何学Cwas applied with every element of the collection, including arrays.

My next try was:

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

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

And it had a following effect when I tried to call that method:

Error 8 The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'MyMethod(T)'

It seems like the compiler doesn't see the MyMethod(T[] array) method. Where am I wrong?

Finally, I provided an auxiliary method:

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

but then I got an error:

Error 8 The type arguments for method 'MyMethodForArray(T[])' cannot be inferred from the usage. Try specifying the type arguments explicitly.

How to manage this problem elegantly?


If it hurts when you do that, don't do that. You'll notice that the List data types in the framework have an Add and an AddRange method. A method that takes an item and a method that takes a collection of items are logically different enough that it makes sense to give them different names. Rather than banging your head against the type system, just change the name of one of them.


Creating a simple program as below

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

the output will be:

Single element method called
Array method called
Single element method called

I suspect you called the method as in line #3 where you were planning to call it as in line #2. Notice that the difference is in the two additional square brackets.


Only have one version of your function (the array version), but declare it with the params keyword like so:

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

Something else you might explore is using IEnumerable<T> rather than T[]

0

精彩评论

暂无评论...
验证码 换一张
取 消