Рассмотрим следующий сценарий:Тип обертки в .NET: struct или class?
int Caller1<T>(T t) where T : IInterface {...}
T Caller2<T>() where T : IInterface {...}
class Wrappee // doesn't implement IInterface, but could
??? Wrapper : IInterface {
private readonly Wrappee _wrappee;
// methods call _wrappee's methods
}
Теперь общие рекомендации по выбору между struct
и class
является «использовать struct
если вам нужно семантику значений и class
для ссылочных семантики». Семантика, которая нам нужна, это «ссылка на Wrappee
». Но, похоже, мы все равно можем сделать Wrapper
struct: копирование его значения - то же самое, что и копирование ссылки Wrappee
, и копии будут иметь ссылку на тот же объект! Накладные расходы ниже, и scalar replacement может уменьшить его до нуля для локальных переменных. Похоже, что можно назвать даже мутирующие методы на _wrappee
.
Я ничего не пропустил? Есть ли веская причина сделать класс Wrapper
?
Существует один, если абонент не является универсальным:
int Caller(IInterface t) {...}
В этом случае Wrapper
должен быть классом, чтобы избежать бокс.
Примечание для тех, кто знает Haskell: Я пытаюсь найти ближайший .NET-аналог до newtype
.
ОБНОВЛЕНИЕ: см. Professional .NET 2.0 Generics и Peter Ritchie on MSDN forums за отсутствие бокса в первом случае.
Почему, по-вашему, использование структуры в качестве параметра типового типа может повлиять на необходимость бокса? –
См. Обновление. –