Как Lazy <T> обойти необходимость в новом() ограничении?
Пример 1 (не компилируется):
void Main()
{
var c = new C<D>();
c.M.F();
}
class C<T>
{
T _m = null;
public T M { get {
if(_m == null) _m = new T();
return _m;
} }
}
class D
{
public void F() { Console.WriteLine ("i was created"); }
}
Результат:
Невозможно создать экземпляр типа переменной 'T', потому что у него нет ограничения new()
Пример 2 (работает):
void Main()
{
var c = new C<D>();
c.M.F();
}
class C<T>
{
Lazy<T> _m = new Lazy<T>();
public T M { get { return _m.Value; } }
}
class D
{
public void F() { Console.WriteLine ("i was created"); }
}
Результат:
i was created
Ответы
Ответ 1
Если вы углубитесь в исходный код, вы увидите, что Lazy<T>
в конечном итоге использует Activator
:
return new Lazy<T>.Boxed((T)Activator.CreateInstance(typeof(T)));
Это просто ярлык для использования отражения. Поскольку он не создает экземпляр типа через фактический аргумент основного типа (new T()
), а скорее вызывает конструктор через отражение, не требуется ограничение where T : new()
.