Когда я тестировал производительность (T)FormatterServices.GetUninitializedObject(typeof(T))
, это было медленнее. В то же время скомпилированные выражения дадут вам значительные улучшения в скорости, хотя они работают только для типов с конструктором по умолчанию. Я выбрал гибридный подход:
public static class New<T>
{
public static readonly Func<T> Instance = Creator();
static Func<T> Creator()
{
Type t = typeof(T);
if (t == typeof(string))
return Expression.Lambda<Func<T>>(Expression.Constant(string.Empty)).Compile();
if (t.HasDefaultConstructor())
return Expression.Lambda<Func<T>>(Expression.New(t)).Compile();
return () => (T)FormatterServices.GetUninitializedObject(t);
}
}
public static bool HasDefaultConstructor(this Type t)
{
return t.IsValueType || t.GetConstructor(Type.EmptyTypes) != null;
}
Это означает, что выражение create эффективно кэшируется и получает штраф только при первой загрузке типа. Также будет эффективно обрабатывать типы значений.
Назовите это:
MyType me = New<MyType>.Instance();
Обратите внимание, что для строки (T)FormatterServices.GetUninitializedObject(t)
произойдет сбой. Следовательно, имеется специальная обработка для возврата пустой строки.