use*_*312 2 .net c# reflection
假设我的sln中有三个项目.
(1) xyz.a{Class Lib}{no reference added}
(2) yzx.b{Class Lib}{added the reference of xyz.a}
(3) zxy.c{Console App}{added the reference of xyz.a}
Run Code Online (Sandbox Code Playgroud)
现在,我需要使用反射从xyz.a中创建驻留在yzx.b中的类的实例.
而且这应该独立于文件夹/目录名.
即使如果我更改yzx.b目录的名称,它应该工作.
有谁有想法吗?
gim*_*lay 10
首先,Activator.CreateInstance()是一种正确的方法.
但是,有一种更有趣的方式:
只需创建调用构造函数的表达式:
public static Func<object[], object> CreateConstructorDelegate(ConstructorInfo method)
{
var args = Expression.Parameter(typeof(object[]), "args");
var parameters = new List<Expression>();
var methodParameters = method.GetParameters().ToList();
for (var i = 0; i < methodParameters.Count; i++)
{
parameters.Add(Expression.Convert(
Expression.ArrayIndex(args, Expression.Constant(i)),
methodParameters[i].ParameterType));
}
var call = Expression.Convert(Expression.New(method, parameters), typeof(object));
Expression body = call;
var callExpression = Expression.Lambda<Func<object[], object>>(body, args);
var result = callExpression.Compile();
return result;
}
Run Code Online (Sandbox Code Playgroud)
性能测试:
public void activator()
{
var stopwatch = new Stopwatch();
const int times = 10000000;
stopwatch.Start();
for (int i = 0; i < times; i++)
{
var v = Activator.CreateInstance(typeof (C));
}
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds + "ms with activator");
var del = CreateConstructorDelegate(typeof(C).GetConstructor(new Type[0]));
stopwatch = new Stopwatch();
stopwatch.Start();
var args = new object[0];
for (int i = 0; i < times; i++)
{
var v = del(args);
}
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds + "ms with expression");
}
Run Code Online (Sandbox Code Playgroud)
输出:
1569ms with activator
134ms with expression
Run Code Online (Sandbox Code Playgroud)
但:
只是为了好奇.
| 归档时间: |
|
| 查看次数: |
4693 次 |
| 最近记录: |