我在这些之间做了一些基准测试(我会写下最基本的细节):
public static T Instance() //~1800 ms
{
return new T();
}
public static T Instance() //~1800 ms
{
return new Activator.CreateInstance<T>();
}
public static readonly Func<T> Instance = () => new T(); //~1800 ms
public static readonly Func<T> Instance = () =>
Activator.CreateInstance<T>(); //~1800 ms
//works for types with no default constructor as well
public static readonly Func<T> Instance = () =>
(T)FormatterServices.GetUninitializedObject(typeof(T)); //~2000 ms
public static readonly Func<T> Instance =
Expression.Lambda<Func<T>>(Expression.New(typeof(T))).Compile();
//~50 ms for classes and ~100 ms for structs
正如 CD 所说,编译表达式是最快的,而且差距很大。所有方法除了(T)FormatterServices.GetUninitializedObject(typeof(T))
仅适用于具有默认构造函数的类型。
当每个泛型类型都有一个静态类时,缓存编译后的结果委托就很简单了。喜欢:
public static class New<T> where T : new()
{
public static readonly Func<T> Instance = Expression.Lambda<Func<T>>
(
Expression.New(typeof(T))
).Compile();
}
请注意new
约束。打电话任何事
MyType me = New<MyType>.Instance();
除了第一次将类加载到内存中之外,执行速度将是最快的。
为了有一个类可以处理带默认构造函数和不带默认构造函数的两种类型,我采用了混合方法,从这里:
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;
}
也将以有效的方式处理值类型。
注意(T)FormatterServices.GetUninitializedObject(t)
将会失败string
。因此,对字符串进行特殊处理以返回空字符串。