Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is is possible to apply a generic method to a list of items?

Tags:

c#

generics

Lets say I've written my own method to reverse a list in place.

public static void MyReverse<T>(List<T> source)
{
    var length = source.Count;
    var hLength = length / 2;
    for (var i = 0; i < hLength; i++)
    {
        T temp = source[i];
        source[i] = source[length - 1 - i];
        source[length - 1 - i] = temp;
    }
}

I call it like so, and it works.

var fooList = new List<Foo>();
MyReverse(fooList);

If I want to reverse multiple lists, I call it like so.

var fooList = new List<Foo>();
var barList = new List<Bar>();
var bazList = new List<Baz>();
MyReverse(fooList);
MyReverse(barList);
MyReverse(bazList);

If I want to reverse an arbitrary number of lists, I'd try:

public static void Main(string[] args)
{
    var lists = new List<object>
    {
        new List<Foo>(),
        new List<Bar>(),
        new List<Bar>()
    };

    ReverseLists(lists);
}

public static void ReverseLists(List<object> sourceLists)
{
    foreach (var sourceList in sourceLists)
    {
        MyReverse(sourceList); // Error: Type arguments cannot be inferred from usage
    }
}

But this throws a compile time error. Is what I'm trying to do possible - could the ReverseLists method be implemented?

like image 739
John Avatar asked Jan 27 '15 12:01

John


1 Answers

Assuming you have a static method like this

public static class ReverseHelper
{
    public static void MyReverse<T>(IList<T> source)
    {
        var length = source.Count;
        var hLength = length / 2;
        for (var i = 0; i < hLength; i++)
        {
            T temp = source[i];
            source[i] = source[length - 1 - i];
            source[length - 1 - i] = temp;
        }
    }
}

With the help of non generic interface and a generic class you can do it.

public interface IReverser
{
    void Reverse();
}
public class ListReverser<T> : IReverser
{
    private readonly IList<T> source;
    public ListReverser(IList<T> source)
    {
        this.source = source;
    }
    public void Reverse()
    {
        ReverseHelper.MyReverse<T>(source);
    }
}
static void Main(string[] args)
{
    var lists = new List<IReverser>
    {
        new ListReverser<Foo>(new List<Foo>()),
        new ListReverser<Bar>(new List<Bar>()),
        new ListReverser<Bar>(new List<Bar>())
    };

    foreach (var reverser in lists)
    {
        reverser.Reverse();
    }
}

I've used IList<T> as opposed to List<T> to support broader number of types; If you want List<T> you can put it back.

like image 186
Sriram Sakthivel Avatar answered Oct 19 '22 12:10

Sriram Sakthivel