Как вернуть общий список?

2

Я даже не думаю, что у меня вопрос правильный, поскольку я только начинаю с дженериков, и мои знания не очень велики.

Скажем, у меня есть следующий метод:

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;
        }
    }
}

И я хотел бы назвать метод следующим:

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

Каков правильный способ сделать это? Я получаю сообщение об ошибке:

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

Я делаю это, потому что структура EdmCmd, переданная методу, имеет разные члены, которые в общем названы. Трудно запомнить, что представляют элементы для каждого CmdType, поэтому я обертываю их в более значимую структуру.

  • 0
    Не совсем ответ, но я думаю, что вы столкнулись с проблемой, что дженерики инвариантны в C # 3.0. С C # 4.0 это будет компилироваться: visualstudiomagazine.com/Articles/2009/05/01/…
Теги:
generics

4 ответа

1
Лучший ответ

Тот факт, что вы ссылаетесь на тип явно в своем общем методе, указывает на то, что у вас проблемы. Компилятору не известно, что List<T> может содержать объект некоторого типа, если этот тип не является T.

Итак, создайте свой список следующим образом:

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;

Это вызовет InvalidCastException во время выполнения, если вы вызовете метод с неправильным типом, но это проблема, которую вы уже должны ожидать.

2

если вы используете

TInfoType[] data

вместо

Array data

в качестве параметра, вы можете использовать

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

int

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

а затем вам не нужно делать новое (вместо этого вы просто используете объекты, переданные в данных). Надеюсь, это даст вам отправную точку.

  • 0
    У меня нет контроля над тем, что находится в массиве. Он уже заполнен элементами EdmCmdData. (Я думаю, я знаю, что вы говорите.)
1
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();
   }
}

Предполагая, что все ваши новые структуры ECmd * действительно структурированы, а не классы с иерархией, вы можете создать список объектов и применить их после обработки переданного массива.

0

Я думаю, что вижу то, что вы пытаетесь сделать, и это действительно невозможно сделать так, как вы хотите в С# 3 и предыдущей версии. Это функция С# 4, хотя, но вам придется подождать несколько месяцев, чтобы пройти RTM.

  • 0
    Таким образом, мне нужно создать метод GetInfo () для каждого типа, который я хочу вернуть? Облом.
  • 0
    Или вы можете просто вернуть базовый тип, а затем в вызывающей функции отфильтровать нужный тип с помощью метода расширения .OfType <DerivedType> () (я думаю, что это в System.Linq)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню