Обычно я бы не советовал этого, но из-за пределов моей головы следующие перегрузки должны охватывать большинство ваших случаев. Они будут охватывать обнуляемые типы и не обнуляемые типы, компилятор выберет соответствующую перегрузку.
public static T nonNeg<T>(T n) where T : struct, IComparable
{
if (n.CompareTo(default(T)) <= 0)
{
return default(T);
}
return n;
}
public static T nonNeg<T>(T? n) where T : struct, IComparable
{
if (!n.HasValue || n.Value.CompareTo(default(T)) <= 0)
{
return default(T);
}
return n.Value;
}