471,337 Members | 862 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,337 software developers and data experts.

Generics and conversion

Hi,

I have classes A1 and A2 which implement the interface IA.
Now I need a method m that works on Lists of objects of either class.
So I wrote something like

void m(List<IA> myList)
{
// do something with myList
}

and wanted to call it like this

main()
{
List<A1> list = new List<A1>();
// fill list
m(list); // <===
// more code
}

Then the compiler complains about the call m(list); with the error
CS1503: cannot convert from 'System.Collections.Generic.List<A1>'
to 'System.Collections.Generic.List<IA>'.

I can use ArrayLists instead of the List<>'s and the problem goes away,
but I have not found a solution using generic collections.
Any suggestions?

TIA

Ralf
Feb 1 '06 #1
8 1499
Hello, Ralf!

RP> I have classes A1 and A2 which implement the interface IA.
RP> Now I need a method m that works on Lists of objects of either class.
RP> So I wrote something like

RP> void m(List<IA> myList)
RP> {
RP> // do something with myList
RP> }

RP> and wanted to call it like this

RP> main()
RP> {
RP> List<A1> list = new List<A1>();
RP> // fill list
RP> m(list); // <===
RP> // more code
RP> }

Use List<IA>list = new List<IA>();

following code will be still valid
list.Add(new A1());
list.Add(new A2());

m(list);

The reason why compiler generated an error is that you specified different types in List<> container in class declaration and in List<> variable declaration in method main(...)

--
Regards, Vadym Stetsyak
www: http://vadmyst.blogspot.com
Feb 1 '06 #2
Ralf,

Instead of passing in List<IA> into your method, you should do this:

void m<T>(List<T> myList) where T : IA
{

}

This way, you can pass the type of T to the method (or in your case, you
can just pass the parameter and it will be inferred).

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Ralf Propach" <ra**@heeg.de> wrote in message
news:dr**********@charly.heeg.de...
Hi,

I have classes A1 and A2 which implement the interface IA.
Now I need a method m that works on Lists of objects of either class.
So I wrote something like

void m(List<IA> myList)
{
// do something with myList
}

and wanted to call it like this

main()
{
List<A1> list = new List<A1>();
// fill list
m(list); // <===
// more code
}

Then the compiler complains about the call m(list); with the error
CS1503: cannot convert from 'System.Collections.Generic.List<A1>'
to 'System.Collections.Generic.List<IA>'.

I can use ArrayLists instead of the List<>'s and the problem goes away,
but I have not found a solution using generic collections.
Any suggestions?

TIA

Ralf

Feb 1 '06 #3
You should use 'where' :

static void MethodName<TItem>(List<TItem> list)
where TItem: IA
{
foreach (TItem item in list)
{
item.DoSome();
}
}

Feb 1 '06 #4
Just to ice the cake you could consider the more general:

void m<T>(IEnumerable<T> sequence) where T: IA
{
}

Unless you really need Count or indexing or can somehow figure out a usefukl
way to add stuff to the list without an input of type T.

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:e6**************@TK2MSFTNGP11.phx.gbl...
Ralf,

Instead of passing in List<IA> into your method, you should do this:

void m<T>(List<T> myList) where T : IA
{

}

This way, you can pass the type of T to the method (or in your case,
you can just pass the parameter and it will be inferred).

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Ralf Propach" <ra**@heeg.de> wrote in message
news:dr**********@charly.heeg.de...
Hi,

I have classes A1 and A2 which implement the interface IA.
Now I need a method m that works on Lists of objects of either class.
So I wrote something like

void m(List<IA> myList)
{
// do something with myList
}

and wanted to call it like this

main()
{
List<A1> list = new List<A1>();
// fill list
m(list); // <===
// more code
}

Then the compiler complains about the call m(list); with the error
CS1503: cannot convert from 'System.Collections.Generic.List<A1>'
to 'System.Collections.Generic.List<IA>'.

I can use ArrayLists instead of the List<>'s and the problem goes away,
but I have not found a solution using generic collections.
Any suggestions?

TIA

Ralf


Feb 1 '06 #5
I would say that this is definitely questionable, since it decreases the
amount of functionality that the OP was looking for in his first post. The
only thing I might change would be co make List<T> IList<T> instead.

IEnumerable<T> only works if you are cycling through the list, and not
making changes of any sort to it.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Nick Hounsome" <nh***@nickhounsome.me.uk> wrote in message
news:X1*********************@fe3.news.blueyonder.c o.uk...
Just to ice the cake you could consider the more general:

void m<T>(IEnumerable<T> sequence) where T: IA
{
}

Unless you really need Count or indexing or can somehow figure out a
usefukl way to add stuff to the list without an input of type T.

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote
in message news:e6**************@TK2MSFTNGP11.phx.gbl...
Ralf,

Instead of passing in List<IA> into your method, you should do this:

void m<T>(List<T> myList) where T : IA
{

}

This way, you can pass the type of T to the method (or in your case,
you can just pass the parameter and it will be inferred).

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Ralf Propach" <ra**@heeg.de> wrote in message
news:dr**********@charly.heeg.de...
Hi,

I have classes A1 and A2 which implement the interface IA.
Now I need a method m that works on Lists of objects of either class.
So I wrote something like

void m(List<IA> myList)
{
// do something with myList
}

and wanted to call it like this

main()
{
List<A1> list = new List<A1>();
// fill list
m(list); // <===
// more code
}

Then the compiler complains about the call m(list); with the error
CS1503: cannot convert from 'System.Collections.Generic.List<A1>'
to 'System.Collections.Generic.List<IA>'.

I can use ArrayLists instead of the List<>'s and the problem goes away,
but I have not found a solution using generic collections.
Any suggestions?

TIA

Ralf



Feb 1 '06 #6
If you reread my post you will see that I said:
Unless you really need Count or indexing or can somehow figure out a
usefukl way to add stuff to the list without an input of type T.

Also there was nothing in the original post that suggested that list
functionality rather than enumerable functionality was required.

Note:
1) It is impossible for m to Add to List<T> as T is not constrained to new()
and even if it was it is not likely that he needs to add default values to
the list.
2) I assume that m does not sort the list or compare T's in any way since it
is not constrained to IComparable
3) In fact T is not constrained to anything at all which means that very
little can be efficiently done on the list.

This makes it rather hard to imagine what the method might be that would
require list rather than enumerable functionality.

In my experience people are always requesting more of their parameters than
is actually required.

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:eY**************@tk2msftngp13.phx.gbl... I would say that this is definitely questionable, since it decreases
the amount of functionality that the OP was looking for in his first post.
The only thing I might change would be co make List<T> IList<T> instead.

IEnumerable<T> only works if you are cycling through the list, and not
making changes of any sort to it.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Nick Hounsome" <nh***@nickhounsome.me.uk> wrote in message
news:X1*********************@fe3.news.blueyonder.c o.uk...
Just to ice the cake you could consider the more general:

void m<T>(IEnumerable<T> sequence) where T: IA
{
}

Unless you really need Count or indexing or can somehow figure out a
usefukl way to add stuff to the list without an input of type T.

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote
in message news:e6**************@TK2MSFTNGP11.phx.gbl...
Ralf,

Instead of passing in List<IA> into your method, you should do this:

void m<T>(List<T> myList) where T : IA
{

}

This way, you can pass the type of T to the method (or in your case,
you can just pass the parameter and it will be inferred).

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Ralf Propach" <ra**@heeg.de> wrote in message
news:dr**********@charly.heeg.de...
Hi,

I have classes A1 and A2 which implement the interface IA.
Now I need a method m that works on Lists of objects of either class.
So I wrote something like

void m(List<IA> myList)
{
// do something with myList
}

and wanted to call it like this

main()
{
List<A1> list = new List<A1>();
// fill list
m(list); // <===
// more code
}

Then the compiler complains about the call m(list); with the error
CS1503: cannot convert from 'System.Collections.Generic.List<A1>'
to 'System.Collections.Generic.List<IA>'.

I can use ArrayLists instead of the List<>'s and the problem goes away,
but I have not found a solution using generic collections.
Any suggestions?

TIA

Ralf



Feb 2 '06 #7
Nicholas Paldino [.NET/C# MVP] wrote:
Ralf,

Instead of passing in List<IA> into your method, you should do this:

void m<T>(List<T> myList) where T : IA
{

}

This way, you can pass the type of T to the method (or in your case, you
can just pass the parameter and it will be inferred).

Hope this helps.


Yes, thanks, this "trick" with the where clause was exactly what I was looking for.

Ralf
Feb 2 '06 #8
"Nick Hounsome" <nh***@nickhounsome.me.uk> wrote in message
news:Cf********************@fe2.news.blueyonder.co .uk...
If you reread my post you will see that I said:
3) In fact T is not constrained to anything at all which means that very
little can be efficiently done on the list.
In the original message, T was constraint to (actually, was) the
interface IA, which could have any number of requirements that we do not
know about.
1) It is impossible for m to Add to List<T> as T is not constrained to new() and even if it was it is not likely that he needs to add default values to
the list.


Nor is there any requirement that items added to the list by m() be
default constructed:

void m<T>(List<T> myList) where T : IA
{
IA a = CreateANewA1orA2();
myList.Add(a);
}

class A1 : IA {}
class A2 : IA {}

IA CreateANewA1orA2()
{
if (DateTime.Now.Millisecond < 500)
return new A1();
else
return new A2();
}
--
Truth,
James Curran
[erstwhile VC++ MVP]

Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
Feb 3 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Tom Jastrzebski | last post: by
3 posts views Thread by Tom Jastrzebski | last post: by
9 posts views Thread by sloan | last post: by
6 posts views Thread by Andrew Ducker | last post: by
7 posts views Thread by Ajeet | last post: by
4 posts views Thread by Random | last post: by
3 posts views Thread by =?Utf-8?B?RnJhbmsgVXJheQ==?= | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.