sproketboy
sproketboy

Reputation: 9468

Generic List method specifying type

In Java I can have a method declaration something like this:

<T> List<T> getList(final Class<T> objectClass, String whatever)

Which means that I specify the list return type by specifying the Class to the method.

List<Customer> customers = getList(Customer.class, "blah");

And if I don't specify the classes properly I get a compile time error. (which is what I'm looking for - I want the compiler to catch a mismatch).

List<String> customers = getList(Customer.class, "blah"); // will not compile

What's the equivalent of this in C#? TIA

Upvotes: 1

Views: 186

Answers (4)

Viacheslav Smityukh
Viacheslav Smityukh

Reputation: 5843

<T> List<T> getList(final Class<T> objectClass, String whatever)

to:

List<T> GetList<T>(string whatever)

List<Customer> customers = getList(Customer.class, "blah");

to:

List<Customer> customers = GetList<Customer>("blah");

List<String> customers = getList(Customer.class, "blah"); // will not compile

to:

List<string> = GetList<Customer>("blah"); // will not compile too

The syntax of the both languages so close

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564871

There is no way in C# to have the compiler infer the generic type based on the return type.

In C#, you must specify T if the only differentiation is the return type:

List<Customer> customer = getList<Customer>("blah");

This method would be written as:

List<T> getList<T>(string whatever) { ... }

However, in C#, type inference is automatically handled if there is a parameter that takes a type of customer. For example, you can have:

List<T> MakeList<T>(params T[] items) { ...}

Then call this as (without <Customer>):

 Customer one = GetCustomer(1);
 Customer two = GetCustomer(2);

 var customers = MakeList(one, two);

Edit in response to comment:

If you are going to be constructing a new "Customer" inside of your method, and want this to work on any type, you'll need a new constraint in place. To have this:

List<Customer> customers = GetList<Customer>("blah");

You would need something like:

List<T> GetList<T>(string whatever) 
   where T : new() // This lets you construct it internally
{
     List<T> results = new List<T>();

     /// ...
     T newInstance = new T();

     results.Add(newInstance);
     return results;
}

That being said, if you're going to make a method like this, chances are you'll also want to have a constraint to an interface, so you can setup the object you create:

List<T> GetList<T>(string whatever) 
   where T : ISomeInterface, new()

This will let you use properties of ISomeInterface within the method, as well as limit it to only working with types that implement that interface.

Upvotes: 3

Random Dev
Random Dev

Reputation: 52300

I think it's just

List<T> GetList<T>(string whatever) { /* ... */ }

you can put a constraint on T like

List<T> GetList<T>(string whatever) 
 where T : class
{ /* ... */ }

if you want to constraint it to classes.

Upvotes: 3

Chandu
Chandu

Reputation: 82943

Try this:

List<T> getList<T>(String whatever) {
.
.
.
.
}

This mandates that the caller specify the type of T while calling the method.

Upvotes: 2

Related Questions