Tutorial :How to return a generic list?



Question:

I don't even think I have the question correct as I am just starting with generics and my knowledge isn't very great.

Say I have the following method:

public class Wrapper  {      public List<TInfoType> GetInfo<TInfoType>(Array data, EdmCmd edmCmd)      {          switch (edmCmd.meCmdType)          {          case EdmCmdType.EdmCmd_PostAdd:              List<EdmCmdPostAddInfo> info = new List<EdmCmdPostAddInfo>();              foreach (EdmCmdData item in data)              {                  info.Add(new EdmCmdPostAddInfo(item.mlObjectID1, item.mlObjectID2, item.mbsStrData1, item.mlLongData1));              }              return info;              break;                          default:              break;          }      }  }  

And I would like to call the method like:

List<EdmCmdPostAddInfo> info = wrapper.GetInfo<EdmCmdPostAddInfo>(data, edmCmd)  

What is the correct way to do this? I am getting the error:

Cannot implicitly convert type 'System.Collections.Generic.List<EPDM.Utils.EdmCmdPostAddInfo>' to 'System.Collections.Generic.List<TInfoType>'  

I am doing this because the EdmCmd struct that is passed to the method has various members that are generically named. It's difficult to remember what the members represent for each CmdType, so I am wrapping them in a more meaningful struct.


Solution:1

The fact that you're referencing a type explicitly in your generic method indicates that you've got trouble. There's no way for the compiler to know that a List<T> can contain an object of some type unless that type is T.

So create your list like this:

result = new List<T>();  foreach (EdmCmdData item in data)  {     object o = new EdmCmdPostAddInfo(item.mlObjectID1, item.mlObjectID2, item.mbsStrData1, item.mlLongData1)     result.Add((T)s);  }  return result;  

This will throw an InvalidCastException at runtime if you invoke the method with the wrong type, but that's a problem you should already be expecting to have.


Solution:2

if you use

TInfoType[] data  

instead of

Array data  

as the parameter, then you can use

List<TInfoType> info = new List<TInfoType>();  

intead of

List<EdmCmdPostAddInfo> info = new List<EdmCmdPostAddInfo>();              

and then you don't need to do the new (instead you just use the objects passed in data). I hope this gives you the starting point.


Solution:3

public class Wrapper  {     public List<TInfoType> GetInfo<TInfoType>(Array data, EdmCmd edmCmd)     {        List<object> info = new List<object>();          switch (edmCmd.meCmdType)        {          case EdmCmdType.EdmCmd_PostAdd:            foreach (EdmCmdData item in data)            {              info.Add(new EdmCmdPostAddInfo(item.mlObjectID1, item.mlObjectID2, item.mbsStrData1, item.mlLongData1));            }            break;                          default:            break;        }          return info.OfType<TInfoType>().ToList();     }  }  

Assuming all of your new ECmd* structures are truly structs and not classes with a hierarchy, you can create a List of objects and cast this after you've processed the passed in array.


Solution:4

I think I see what you're trying to do, and it's not really possible to do it like you want to in C# 3 and previous version. This is a feature of C# 4 though, but you'll have to wait for a few months for that to go RTM.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »