Я намеренно проверяю только null
, потому что не хочу ограничивать значение ValueType равным default(T)
Это хорошее понимание, но не волнуйтесь, вы уже покрыты этим. Недопустимо сравнивать T с default(T)
, используя, в первую очередь, ==
; Разрешение перегрузки не найдет уникального лучшего оператора ==
.
Конечно, вы можете сделать сравнение с .Equals
, но тогда вы рискуете аварийно завершить работу, если получатель имеет нулевое значение, чего вы и пытаетесь избежать.
Есть ли более стандартный способ справиться с этой ситуацией?
Нет. Сравнение с нулем - это то, что нужно делать здесь.
Как указано в разделе 7.10.6 в спецификации C #: " Конструкция x == null
разрешена, даже если T может представлять тип значения, а результат просто определяется как false, когда T является типом значения."
Есть ли вероятность возникновения проблемы из-за этого?
Конечно. То, что код компилируется, не означает, что он имеет семантику, которую вы намереваетесь. Напишите несколько тестов.
Что действительно происходит под капотом, когда я звоню и передаю тип значения?
Вопрос неоднозначный. Позвольте мне перефразировать его на два вопроса:
Что на самом деле происходит под капотом, когда я выполняю вызов универсального метода с аргументом типа, который является необнуляемым типом значения?
Джиттер компилирует метод при первом вызове с этой конструкцией. Когда джиттер обнаруживает нулевую проверку, он заменяет ее на «ложь», потому что он знает, что ни один тип значения, не имеющий значения NULL, никогда не будет равен нулю.
Что действительно происходит под капотом, когда я выполняю вызов универсального метода с аргументом типа, который является ссылочным типом, но аргументом, который является структурным типом? Например:
interface IFoo : ISomeInterface<IFoo> {}
struct SFoo : IFoo { whatever }
...
DoFooInternal<IFoo>(new SFoo());
В этом случае дрожание не может исключить нулевую проверку, а сайт вызова не может избежать бокса. Экземпляр SFoo будет упакован, и будет проверена ссылка на SFoo в штучной упаковке, чтобы определить, является ли он нулевым.