user4284351
user4284351

Reputation:

C# Working with a generic list in a method

I have been teaching myself generics and I wanted to try it out with a list but I struggled upon a problem I cant figure out how to "feed" the generic list to my method. What is the proper way to make a generic method "eat" my list? :)

Heres my code:

 class Program<AnyDataType>
{
    static void Main(string[] args)
    {
        jdtlist.Add("something");
        jdtlist.Add("something");
        jdtlist.Add("something");
        Console.WriteLine(countlist(jdtlist));
        Console.ReadKey();
    }
    static List<AnyDataType> jdtlist = new List<AnyDataType>();

    public static int countlist(List<AnyDataType> list) // Yes I know this is practically useless but thats not why I am here :)
    {
        int listcount = 0;
        for (int i = 0; i < list.Count; i++)
        {
            listcount++;
        }
        return listcount;
    }

Upvotes: 1

Views: 2056

Answers (4)

Jon Hanna
Jon Hanna

Reputation: 113382

Okay you have:

public static int countlist(List<AnyDataType> list)
{
    int listcount = 0;
    for (int i = 0; i < list.Count; i++)
    {
        listcount++;
    }
    return listcount;
}

And well, it works fine, but only if you have List<AnyDataType> to begin with.

Well, you could do:

public static int Countlist<T>(List<T> list)
{
    int listcount = 0;
    for (int i = 0; i < list.Count; i++)
    {
        listcount++;
    }
    return listcount;
}

Now the method itself is generic. What's more overloads will happen automatically in that you can call CountList(new List<string>()) rather than having to explicitly call CountList<strong>(new List<string>()).

But this combines with simple matters of inheritance. Consider that your CountList could work just as well with any other IEnumerable<T> implementation:

public static int Count<T>(IEnumerable<T> source)
{
  int tally = 0;
  foreach(var item in source)
    ++tally;
  return tally;
}

So just as generics mean you don't have to restrict yourself to a particular type of list, so normal inheritance and interface implementation means you can work with the most general case applicable.

Upvotes: 0

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236308

If you are writing generic method, then it should have generic parameter

public static int CountList<T>(List<T> list)
{
    int listcount = 0;

    for (int i = 0; i < list.Count; i++)        
        listcount++;

    return listcount;
}

Then you can call it with any generic list

var list = new List<AnyDataType>();
// ..
Foo.CountList(list);

Same goes to classes. If you want to parametrize class with some generic type, you should provide generic argument

public class Foo<T>

As @DStanley stated, you don't need to parametrize individual methods in that case

public class Foo<T>
{
    public static int CountList(List<T> list)
    {
        int listcount = 0;

        for (int i = 0; i < list.Count; i++)        
            listcount++;

        return listcount;
    } 
}

But you need to parametrize class

Foo<int>.CountList(list)

Suggested reading: Generics (C# Programming Guide)

Upvotes: 4

Tim Schmelter
Tim Schmelter

Reputation: 460340

You need to call the static method of the generic class via class-name including the type of the parameter:

so instead of

Console.WriteLine(countlist(jdtlist));

this:

Console.WriteLine(Program<string>.countlist(jdtlist));

Another way is to make the method generic, not the class:

public static int countlist<AnyDataType>(List<AnyDataType> list) {}

Then you can call it in these ways(with explicit type or inferred from parameter):

Program1.countlist<string>(jdtlist)
Program1.countlist(jdtlist)

Upvotes: 0

D Stanley
D Stanley

Reputation: 152634

Your problem is not passing the list to your method - that part is fine. Your problem is that you're trying to fill a "generic" list with a "specific" type (namely strings). Making a class generic means "I am not specifying the data type here - the consumer of the class will do that". So a better use case for your class would be:

class Program
{
    static void Main(string[] args)
    {
        MyList<string>.Add("something");
        MyList<string>.Add("something");
        MyList<string>.Add("something");
        Console.WriteLine(MyList<string>.countlist(MyList<string>.jdtlist));
        Console.ReadKey();
    }
}
public class MyList<AnyDataType>
{
    public static List<AnyDataType> jdtlist = new List<AnyDataType>();

    public static void Add(AnyDataType item)
    {
        jdtList.Add(item);
    }

    public static int countlist(List<AnyDataType> list) 
    {
        int listcount = 0;
        for (int i = 0; i < list.Count; i++)
        {
            listcount++;
        }
        return listcount;
    }

This is the minimum needed to get your program to work - there are several improvements that can be made (not using static so much, etc.) but hopefully it helps you understand generics better.

Upvotes: 0

Related Questions