Почему я получаю "ошибка:... должен быть ссылочным типом" в моем общем методе С#?
В разных таблицах базы данных у меня есть как свойство, так и значение. Я использую Linq to SQL для доступа к базе данных.
Я пишу метод, который возвращает словарь, содержащий свойства/значения, полученные из данной таблицы базы данных:
private static Dictionary<string, string> GetProperties<T>(Table<T> table)
{
Dictionary<string, string> properties = new Dictionary<string, string>();
foreach (var row in table)
{
properties[row.Property]=row.Value;
}
return properties;
}
При компиляции я получаю:
Error 1 The type 'T' must be a reference type in order to use it as parameter 'TEntity' in the generic type or method 'System.Data.Linq.Table<TEntity>'
Я попытался найти это сообщение об ошибке без ведома.
Поиск StackOverflow, этот вопрос кажется похожим, хотя в отношении параметра List: Generic List <T> как параметр на методе - хотя параметр все еще не является ссылочным типом в ответах на этот вопрос.
Чтение руководства по программированию на С# в MSDN: http://msdn.microsoft.com/en-us/library/twcad0zb(VS.80).aspx Я вижу, что их примеры передают параметры по ссылке. Тем не менее, я не вижу, как проходить по ссылке в моем конкретном случае, поскольку общий тип предназначен только для указания общего типа таблицы.
Любые указатели будут высоко оценены.
PS: Приложения, если для меня требуется время, чтобы принять ответ, поскольку эта функция в настоящее время недоступна (я слепой и использую программу чтения с экрана).
Ответы
Ответ 1
Это происходит из-за того, как объявлен Table<T>
:
public sealed class Table<TEntity> : IQueryable<TEntity>,
IQueryProvider, IEnumerable<TEntity>, ITable, IQueryable, IEnumerable,
IListSource
where TEntity : class // <-- T must be a reference type!
Компилятор жалуется, потому что ваш метод не имеет ограничений на T
, что означает, что вы можете принять T
, который не соответствует спецификации Table<T>
.
Таким образом, ваш метод должен быть как минимум строгим в отношении того, что он принимает. Вместо этого попробуйте:
private static Dictionary<string, string> GetProperties<T>(Table<T> table) where T : class
Ответ 2
Просто добавьте ограничение where T : class
к объявлению метода.
Это требуется, потому что Table<TEntity>
имеет ограничение where TEntity : class
. В противном случае ваш общий метод можно вызвать с помощью параметра типа struct, для чего CLR должен создать экземпляр Table<TEntity>
с этим параметром типа struct, который нарушит ограничение на Table<TEntity>
.
Ответ 3
public class TEntityRepository<TEntity> : EFRepository<TEntity> , ITEntityRepository<TEntity>
where TEntity : class, new()
{
}