Справка с ошибкой С# generics - "Тип" T "должен быть невообразимым типом значения"
Я новичок в С# и не понимаю, почему следующий код не работает.
public static Nullable<T> CoalesceMax<T>(Nullable<T> a, Nullable<T> b) where T : IComparable
{
if (a.HasValue && b.HasValue)
return a.Value.CompareTo(b.Value) < 0 ? b : a;
else if (a.HasValue)
return a;
else
return b;
}
// Sample usage:
public DateTime? CalculateDate(DataRow row)
{
DateTime? result = null;
if (!(row["EXPIRATION_DATE"] is DBNull))
result = DateTime.Parse((string)row["EXPIRATION_DATE"]);
if (!(row["SHIPPING_DATE"] is DBNull))
result = CoalesceMax(
result
DateTime.Parse((string)row["SHIPPING_DATE"]).AddYears(1));
// etc.
return result;
}
Во время компиляции он дает следующую ошибку:
Тип 'T' должен быть невообразимым типом значения, чтобы использовать его как параметр 'T' в общем типе или методе 'System.Nullable <T> '
Ответы
Ответ 1
Вам нужно добавить ограничение T : struct
:
public static Nullable<T> CoalesceMax<T>
(Nullable<T> a, Nullable<T> b) where T : struct, IComparable
В противном случае С# попытается понять, что означает Nullable<T>
, и поймет, что у него еще нет ограничения, требуемого самим Nullable<T>
. Другими словами, вы можете попробовать позвонить:
CoalesceMax<string>(...)
что не имеет смысла, так как Nullable<string>
недействителен.
Ответ 2
Тип Nullable<T>
имеет ограничение на него, для которого T
требуется тип значения (struct
в С#). Вот почему компилятор говорит вам о Nullable<T>
, а не о вашей функции или сайте вызова этой функции - это класс Nullable
, который является основной причиной ошибки, поэтому на самом деле это более полезно, если только компилятор просто указал на вашу функцию и сказал: "Это неправильно, исправьте!" (Предположим, что если CoalesceMax
использовал несколько дженериков и нарушил ограничение только на одном из них - было бы более полезно узнать, какой из родословных нарушил его ограничение, а просто знать, что одно или несколько ограничений в CoalesceMax
были сломаны).
Решение состоит в том, чтобы сделать ваши T
и их T
совместимыми, введя такое же ограничение. Это делается путем добавления ограничения struct
, которое должно появиться перед всеми интерфейсами/новыми ограничениями:
public static Nullable<T> CoalesceMax<T>(Nullable<T> a, Nullable<T> b) where T : struct, IComparable{
...
}
Ответ 3
В вашем общем методе используется Nullable<T>
.
Однако вы не ограничиваете тип T
, поэтому он может оказаться Nullable<Form>
, что явно недействительно.
Вам нужно изменить ограничение на where T : struct, IComparable
, чтобы гарантировать, что T
может быть только типом значения.
Ответ 4
Не совсем ответ на OP, но поскольку это первое, что появилось в google для того же сообщения об ошибке, мне пришлось добавить ограничение на определение моего класса, а не мой метод, например
public class MyClass<T> where T : struct
{
public void MyMethod(T? value)
{
}
}