Я искал способы сделать ленивую инициализацию и нашел Lazy<T>
, который включен в .NET 4.
Я думал о развертывании моей собственной реализации Lazy<T>
для.NET 3.5 (с более простой многопоточной политикой), и я столкнулся со следующей проблемой:
У Lazy в основном два типа конструкторов:
class Lazy<T> {
public Lazy(){...} // ctor #1
, который использует конструктор по умолчанию для Tсоздание экземпляра T и
public Lazy(Func<T> func){...} // ctor #2
, который позволяет вызывающей стороне решать, как создается экземпляр T.
Теперь вот проблема:
Если я хочу скомпилировать-время проверки для 1-го ctor'а я добавлю ограничение
class Lazy<T> where T: new() {...}
на уровне класса.Это позволит мне использовать new T()
для создания экземпляра;но это ограничение не является обязательным для второго ctor, и, что еще хуже, оно также ограничивает типы, которые я могу использовать (для типов с ctor по умолчанию)
Если я хочу иметь возможность использовать любой тип со вторым ctorЯ не буду устанавливать никаких ограничений, и в 1-м ctor будет использовать отражение, чтобы убедиться, что T
имеет ctor по умолчанию.Однако при таком подходе будет отсутствовать проверка во время компиляции, и будет генерироваться исключение во время выполнения, только если 1-й код используется с неправильным типом.
Мой вопрос: могу ли я получить лучшее из обоих миров?
В идеале я хотел бы получить проверку во время компиляции для каждого использования ctor # 1, но в то же время иметь возможность использовать ctor # 2 для типов, которые не имеют ctor по умолчанию.
Как реализация Microsoft делает это?(У меня нет легкого доступа к источникам или библиотекам .NET 4).
РЕДАКТИРОВАТЬ: (После "Отражения" сборки MS)
Я проверил эталонную реализацию, и онане выполняет проверки во время компиляции.
Он использует отражение для случая 'ctor по умолчанию', конечно, сопровождается исключением времени выполнения, если дела идут плохо.