Я даже не думаю, что у меня вопрос правильный, поскольку я только начинаю с дженериков, и мои знания не очень велики.
Скажем, у меня есть следующий метод:
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, поэтому я обертываю их в более значимую структуру.
Тот факт, что вы ссылаетесь на тип явно в своем общем методе, указывает на то, что у вас проблемы. Компилятору не известно, что 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
во время выполнения, если вы вызовете метод с неправильным типом, но это проблема, которую вы уже должны ожидать.
если вы используете
TInfoType[] data
вместо
Array data
в качестве параметра, вы можете использовать
List<TInfoType> info = new List<TInfoType>();
int
List<EdmCmdPostAddInfo> info = new List<EdmCmdPostAddInfo>();
а затем вам не нужно делать новое (вместо этого вы просто используете объекты, переданные в данных). Надеюсь, это даст вам отправную точку.
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 * действительно структурированы, а не классы с иерархией, вы можете создать список объектов и применить их после обработки переданного массива.
Я думаю, что вижу то, что вы пытаетесь сделать, и это действительно невозможно сделать так, как вы хотите в С# 3 и предыдущей версии. Это функция С# 4, хотя, но вам придется подождать несколько месяцев, чтобы пройти RTM.