#c# #.net #generics
#c# #.net #дженерики
Вопрос:
Я изо всех сил пытаюсь написать общие методы для сохранения и загрузки данных из базы данных Sterling.
Это мой метод сохранения:
public static void SaveList<T>(List<T> listToSave)
{
foreach (T listItem in listToSave)
{
DatabaseInstance.Save(listItem);
}
}
Я получаю волнистую красную строку при сохранении и ошибку «Тип T должен быть ссылочным типом, чтобы использовать его в качестве параметра T»
Это мой метод загрузки:
public static List<T> LoadList<T>()
{
List<T> list = (from index in DatabaseInstance.Query<T, int>() select index.Key).ToList();
return list;
}
Я получаю ту же ошибку.
Есть идеи?
Приветствия
Стив
Обновить:
Я добавил класс where T:, как было предложено, и получил сообщение об ошибке:
Тип T должен иметь общедоступный конструктор без параметров, чтобы использовать его в качестве параметра
Следуя инструкциям в ссылке, предоставленной Брайаном, я добавил new() в конце, и теперь все работает.
Ответ №1:
Вам нужно ограничение универсального типа для вашего определения:
public static void SaveList<T>(List<T> listToSave) where T : class
{
foreach (T listItem in listToSave)
{
DatabaseInstance.Save(listItem);
}
}
public static List<T> LoadList<T>() where T : class
{
List<T> list = (from index in DatabaseInstance.Query<T, int>() select index.Key).ToList();
return list;
}
Комментарии:
1. Выбрано в качестве ответа из-за ссылки на информацию об ограничении общего типа, которая помогла с дальнейшими ошибками.
Ответ №2:
Чтобы исправить ваш код, вам нужно общее ограничение, которое принудительно вводит ссылочный тип, как показано ниже. Чтобы выделить этот ответ из других, уже опубликованных, я также рекомендую вам использовать IEnumerable<T>, а не List<T>:
public static void SaveList<T>(IEnumerable<T> itemsToSave) where T : class
{
foreach (T item in itemsToSave)
{
DatabaseInstance.Save(listItem);
}
}
public static IEnumerable<T> LoadList<T>() where T : class
{
return (from index in DatabaseInstance.Query<T, int>()
select index.Key);
}
Изменение на IEnumerable<T> должно быть совместимо со всем вашим существующим кодом, поскольку List<T> уже реализует IEnumerable<T> . При правильном использовании это также позволит вам получить хороший прирост производительности за счет одновременного хранения меньшего количества элементов в оперативной памяти и сделает ваш код более мощным, позволяя ему работать с другими типами коллекций.
Комментарии:
1. Эти два метода заслуживают переименования. Может
SaveItems
быть, иGetItems
?
Ответ №3:
Проблема в том, что в вашем существующем коде T может быть чем угодно. Это не нормально, потому Save
что функция принимает только ссылочные типы.
Вам нужно установить ограничение, которое фактически обязывает компилятор, что T будет ссылочным типом.
public static void SaveList<T>(List<T> listToSave) where T : class
{
foreach (T listItem in listToSave)
{
DatabaseInstance.Save(listItem);
}
}
Ответ №4:
можете ли вы попробовать?
public static void SaveList<T>(List<T> listToSave) where T:class
{
foreach (T listItem in listToSave)
{
DatabaseInstance.Save(listItem);
}
}
Ответ №5:
Попробуйте добавить class
ограничение:
public static void SaveList<T>(List<T> listToSave) where T : class
{
foreach (T listItem in listToSave)
{
DatabaseInstance.Save(listItem);
}
}
public static List<T> LoadList<T>() where T : class
{
List<T> list = (from index in DatabaseInstance.Query<T, int>()
select index.Key).ToList();
return list;
}