Can a method tabe both a collection and a generic list

T

Tony Johansson

Hello!

If I have a method named Foo in this way.
public X Foo(Y myList)
{
....
}

Here I would be able se pass an ArrayList or an List<T> as Y and
return the same thing as X. Is that possible ?

//Tony
 
F

Felix Palmen

* Tony Johansson said:
If I have a method named Foo in this way.
public X Foo(Y myList)
{
...
}

Here I would be able se pass an ArrayList or an List<T> as Y and
return the same thing as X. Is that possible ?

Not exactly like that, but you could use a type parameter:

public T Foo<T>(T myList) where T : IEnumerable
 
T

Tony Johansson

Peter Duniho said:
As Felix says, if you make the method generic, then the return type can
vary according to the parameter type.

However, note that making the method generic isn't necessarily going to
solve the real issue. It's one thing to fix the declaration. It's yet
another for the code in the method to be able to successfully _use_ the
argument passed to it and return an object of the same type.

In Felix's example, he uses a constraint of IEnumerable for the generic
type. That would be sufficient if, for example, you are simply returning
the same object that is passed to the method. However, if you expect to
return a new instance of your type parameter T, then presumably you'll
need to initialize that object somehow. And in that case, a constraint of
IEnumerable is not enough because IEnumerable is read-only.

If you can use a constraint of a modifiable type, such as IList<T> or
ICollection<T>, then that could work. But otherwise, you have other
problems besides the return type.

Pete

Here is an example of what I want to do.
This is somewhat pseducode because I call EnterStudentData() in a different
class in a way that wouldn't work.
I have two classes that call the method EnterStudentData(). When I call
EnterStudentData() from class CollectionTask2 I want to pass an ArrayList as
a argument to the EnterStudentData().
When I call EnterStudentData() from class CollectionTask4 I want to pass an
List<Student> as an argument to the EnterStudentData().
I also want to return the same type as was passed into the
EnterStudentData() out of the EnterStudentData()

How would I write the definition for EnterStudentData ?
How would I write the statement that will call the EnterStudentData() ?

class CollectionTask2
{
ArrayList studList = new ArrayList();

public void StartCollectionTask2()
{
EnterStudentData();
}
}


class CollectionTask4
{
List<Student> studList = new List<Student>();
public void StartCollectionTask4()
{
EnterStudentData();
}
}

class Test
{
public T EnterStudentData<T>(T studList) where T : IEnumerable<T>
{
...
return T;
}
}

//Tony
 
T

Tony Johansson

Peter Duniho said:
Tony said:
[...]
When I call EnterStudentData() from class CollectionTask4 I want to pass
an List<Student> as an argument to the EnterStudentData().
I also want to return the same type as was passed into the
EnterStudentData() out of the EnterStudentData()

Yes, all that was clear from your first question.
How would I write the definition for EnterStudentData ?

Impossible to say. You have not explained what instance you want to
return from the method, nor how you intend to create or otherwise obtain
it, if not the same instance passed to the method.
How would I write the statement that will call the EnterStudentData() ?

ArrayList list1, list2;

// initialize list1 somehow

list2 = EnterStudentData(list1);

List<Student> list3, list4;

// initialize list3 somehow

list4 = EnterStudentData(list3);

Pete

If I pass an ArrayList to EnterStudentData I will return the same instance
that was passed to EnterStudentData and if I pass an List<Student> to
EnterStudentData I will return the same instance List<Student> from the
EnterStudentData .

Can you give me a hint how I write the definition of EnterStudentData ?
//Tony
 
T

Tony Johansson

Peter Duniho said:
Here is a generic method that simply returns the instance of an object
that was passed to it:

T Identity<T>(T t)
{
return t;
}

Pete


Here I have a complete program that give the compile error Error 1 'T' does
not contain a definition for 'Add'
I'm not so good at generic method. Is it possible to change so method
AddStudent can add an instance to the passed argument ?
I can't understand why the compiler complains about T does not contain a
definition for Add ?

public class Program
{
public static void AddStudent<T>(T source)
{
source.Add(new Student());
}

static void Main(string[] args)
{
ArrayList studList1 = new ArrayList();
NotWorkingMethod(studList1);

List<Student> studList2 = new List<Student>();
NotWorkingMethod(studList2);
}
}

class Student {}

//Tony
 
T

Tony Johansson

Peter Duniho said:
Because it doesn't. You've done nothing for your generic method to
constrain T to a type that includes an Add() method, so when the generic
method is compiled, it doesn't contain an Add() method.

You need to remember that generics need to be valid when they are
_compiled_, not when they are used elsewhere. At the time they are
compiled, the compiler doesn't know anything about the type that will be
used for the type parameter, except those constraints you specify.

This is _exactly_ why I wrote the comments I wrote before, about the
method implementation being workable. If you can include a constraint of
IList (which you can, if the only two types you're going to use with the
method are ArrayList and List<T>), then you'll find the compiler can be
made to understand that the type T has an Add() method.

Pete

many thanks Pete!!
Yes it worked now when I did what you say
public static void AddStudent<T>(T source) where T : IList
{
source.Add(new Student());
}

//Tony
 
K

kndg

many thanks Pete!!
Yes it worked now when I did what you say
public static void AddStudent<T>(T source) where T : IList
{
source.Add(new Student());
}

//Tony

Or (if you feel lazy), you could use one of the C# 4 blessing(?)...

public static dynamic AddStudent(dynamic source)
{
source.Add(new Student());

return source;
}

There may be times that it could turn into disaster.

Regards.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top