Ответ, который задает спрашивающий вопрос, обычно считается правильным подходом.Если у вас есть универсальный метод, который должен сделать что-то особенное для одного конкретного типа, он больше не generic .
При этом, во-первых, на настоящий вопрос так и не был получен ответ, а во-вторых, есть некоторые оговорки в отношении этого подхода, которые необходимо рассмотреть.
Это не работает, поскольку в нем говорится "не может преобразовать"Т, чтобы удвоить ".Есть ли способ исправить это?
Да, есть несколько способов сделать это, и некоторые из них лучше, чем другие.
Во-первых, это вВообще, плохой способ набрать test.
typeof(T) == typeof(double)
У вас есть два Ts в руке, поэтому вместо этого вы должны сделать следующее:
protected void Set<T>(ref T storage, T value, blah blah blah)
{
if (Equals(storage, value))
return;
double? oldValue = storage as double?;
double? newValue = value as double?;
if (oldValue != null && newValue != null && Negligible(oldValue.Value, newValue.Value))
return;
...
Обратите внимание, что плохой способ сделать это:
protected void Set<T>(ref T storage, T value, blah blah blah)
{
if (Equals(storage, value))
return;
if (storage is double && value is double)
{
double oldValue = (double)(object)storage;
double newValue = (double)(object)value;
if (Negligible(...
Потому что это требует штрафа за бокс;джиттер не обязательно достаточно умен, чтобы оптимизировать двойной -> объект -> двойной шаг, который стоит дорого.
Хотя, как я уже сказал, в целом, по возможности, лучше специализироваться, подумайтеследующая ситуация.Если вы специализируетесь и создаете одну версию, которая удваивает, и ту, которая делает все остальное, то:
Set(ref someDouble, 1.23)
вызовет двойную версию, но
Set<double>(ref someDouble, 1.23)
будет по-прежнему вызыватьуниверсальная версия .C # предпочитает неуниверсальную версию универсальной версии, но если вы явно запросите универсальную версию, вы получите ее.
Точно так же, если вы звонили из общего контекста:
class C<T>
{
T storage;
void Frob(Blah blah, T value) {
blah.Set<T>(ref storage, value);
}
Тогда C<double>
не вызывает вашу специальную версию;опять же, это вызывает Set<double>
в соответствии с просьбой.
Так что будьте осторожны.