C# 使用反射实例化类
假设我的sln中有三个项目C# 使用反射实例化类,c#,.net,reflection,C#,.net,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} 现在,我需要使用反射从xyz.a中创建驻留在yzx.b中的类的实例 而且这应该独立于文件夹/目录名 也就是说,即使我更改了yzx.b目录的名称,它也应该可以工作 有人知道吗?你可能
(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}
现在,我需要使用反射从xyz.a中创建驻留在yzx.b中的类的实例
而且这应该独立于文件夹/目录名
也就是说,即使我更改了yzx.b目录的名称,它也应该可以工作
有人知道吗?你可能想看看这些方法。只需将程序集的名称和类型传递给它
如果没有对程序集的编译时引用,您仍然可以在运行时使用引用它。您可以使用来轻松创建实例(这也可以缓存各种反射信息以更快地进行重复调用),或者如果您希望通过构造函数本身进行反射并直接运行它(通过)首先,Activator.CreateInstance()是一种正确的方法。 但是,还有一种更有趣的方式:
- 快10倍
- 不要将异常包装在 目标异常
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;
}
但是:
- 仅限C#3.0版
- Complile()是长时间运行的操作
只是出于好奇。JMSA,我只想说一句关心的话,如果你问的是DAL/循环依赖问题,那么你就越走越远了。@Henk Holterman,我知道有人会告诉我这一点。但是我还能做什么呢?@Henk Holteman,没有其他方法可以解决这个问题。这个问题的答案可能会给你指出一个更好的方向:也许你应该将这个项目解耦,并使用类似StructureMap的东西?“首先,Activator.CreateInstance()是一个正确的方法”。这是什么评论?你在说什么??
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");
}
1569ms with activator
134ms with expression