需求:使用泛型创建有参数的对象(性能上考虑,不使用反射创建)。
使用泛型创建无参(默认)构造函数的对象可以用
where :T ,new()
new T();
来实现,但是如果构造函数带有参数怎么办呢?
于是就写了一下一段代码:
这里使用了Expression 和 LambdaExpression,目的是为了生成对应类构造函数的委托
,所以第一次调用会相对慢一点,随后调用就像直接new一样快,适合多次调用情况。
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace XXX
{
/// <summary>
/// ObjectCreator class used to create object at runtime.
/// </summary>
public class ObjectCreator<T>
{
#region Singleton
private ObjectCreator() { }
public static ObjectCreator<T> Instance
{
get { return Nested.m_instance; }
}
private class Nested
{
static Nested() { }
internal static readonly ObjectCreator<T> m_instance = new ObjectCreator<T>();
}
#endregion
private ObjectActivator m_rowCreatedActivator = null;
/// <summary>
/// Constructor of delegate
/// </summary>
/// <typeparam name="T">Type</typeparam>
/// <param name="args">arguments of Constructor</param>
/// <returns>Type</returns>
private delegate T ObjectActivator(params object[] args);
public T Create(Type[] types, params object[] args)
{
if (null == m_rowCreatedActivator)
{
m_rowCreatedActivator = ObjectCreator<T>.Instance.GetActivator(typeof(T).GetConstructor(types));
}
return m_rowCreatedActivator(args);
}
/// <summary>
/// Create object type at runtime.
/// </summary>
/// <typeparam name="T">Type</typeparam>
/// <param name="ctor">ConstructorInfo of Type</param>
/// <returns>Constructor of delegate</returns>
private ObjectActivator GetActivator(ConstructorInfo ctor)
{
ParameterInfo[] paramsInfo = ctor.GetParameters();
//create a single param of type object[]
ParameterExpression param = Expression.Parameter(typeof(object[]), "args");
Expression[] argsExp = new Expression[paramsInfo.Length];
//pick each arg from the params array
//and create a typed expression of them
for (int i = 0; i < paramsInfo.Length; i++)
{
Expression index = Expression.Constant(i);
Type paramType = paramsInfo[i].ParameterType;
Expression paramAccessorExp = Expression.ArrayIndex(param, index);
Expression paramCastExp = Expression.Convert(paramAccessorExp, paramType);
argsExp[i] = paramCastExp;
}
//make a NewExpression that calls the
//ctor with the args we just created
NewExpression newExp = Expression.New(ctor, argsExp);
//create a lambda with the New
//Expression as body and our param object[] as arg
LambdaExpression lambda = Expression.Lambda(typeof(ObjectActivator), newExp, param);
//compile it
ObjectActivator compiled = (ObjectActivator)lambda.Compile();
return compiled;
}
}
}
分享到:
相关推荐
C#,泛型C#,泛型C#,泛型C#,泛型C#,泛型C#,泛型C#,泛型
C#泛型、反射实例,分层,自动生成sql语句
反射和泛型是一种重要的解决途径。 此代码是一个生成泛型对象的类。 比如: Pool<Point> pool = new Pool(){}; Point p = pool.get(x, y); //在此构造Point对象 ... pool.put(p); 希望能帮助那些为查找泛型构造器、...
C#泛型集合使用实例C#泛型集合使用实例C#泛型集合使用实例
C#的泛型C#的泛型
.net,C# 泛型示例代码.net,C# 泛型示例代码.net,C# 泛型示例代码
泛型类、泛型方法、泛型接口、泛型委托 泛型类、泛型方法、泛型接口、泛型委托
C#泛型类创建的链表
C# 泛型的好处C# 泛型的好处C# 泛型的好处
C#泛型,非泛型实现枚举功能,通过实现接口方法或者使用迭代器块实现
C#泛型详解文档附实战实例代码,适合C#进阶人群,代码100%能正常运行,有问题可留言!
c#泛型类、泛型方法、泛型接口、泛型委托
在C#中通过反射操作一个List泛型。。
C# 实现泛型接口
c# 泛型应用实例, c#(vs2008)
C#【泛型】实现的【通用】结构体转字节数组,包含网上收集的网页参考资料、非通用的【StructTest】工程、泛型实现的通用【Struct2BytesGenericType】工程。 VS2010编译运行。
C#泛型使用小案例 c#经典案例.pdf
C#泛型详解
在.NET FCL为我们提供了很多集合类型,是编程中非常有力的工具。泛型集合主要在 System.Collections.Generic名称空间中,而非泛型集合主要在System....2.泛型集合在性能和类型安全方面优于非泛型集 合。 。。。。
c#泛型与集合编程.pdf