C# 如何发出委托或lambda表达式
我想发出一个返回Func的方法。在这个方法中,我必须创建一个委托或一个lambda表达式,它正好服务于返回类型 总之,它应该是这样的:C# 如何发出委托或lambda表达式,c#,delegates,lambda,reflection.emit,C#,Delegates,Lambda,Reflection.emit,我想发出一个返回Func的方法。在这个方法中,我必须创建一个委托或一个lambda表达式,它正好服务于返回类型 总之,它应该是这样的: // I have a resolve method that will be called inside my missing method // This is it's signature: object Resolve( params object[] args); // This is how I use it: var barFactory = (
// I have a resolve method that will be called inside my missing method
// This is it's signature:
object Resolve( params object[] args);
// This is how I use it:
var barFactory = ( Func<IBar> )MissingMethod( typeof( IBar ) );
var bar = barFactory.Invoke();
// or - with one string argument:
var fooFactory = ( Func<string, IFoo> )MissingMethod( typeof( IFoo ), typeof( string ) );
var foo = fooFactory.Invoke( "argument for foo" );
Container.Resolve<Foo>( "argument" );
我的代表应该看起来像
delegate void object LateBoundMethod( object[] arguments );
并且目标作为实例字段提供。通过采用和“改进”Marc的解决方案,我得到:
private Delegate CreateDelegate( Type returnType, Type[] parameterTypes )
{
m_Type = returnType;
var i = 0;
var param = Array.ConvertAll( parameterTypes, arg => Expression.Parameter( arg, "arg" + i++ ) );
var asObj = Array.ConvertAll( param, p => Expression.Convert( p, typeof( object ) ) );
var argsArray = Expression.NewArrayInit( typeof( object ), asObj );
var callEx = Expression.Call( null, typeof( FuncFactory ).GetMethod( "Resolve" ), argsArray );
var body = Expression.Convert( callEx, returnType );
var ret = Expression.Lambda( body, param ).Compile();
return ret;
}
private readonly Container m_Container;
private Type m_Type;
public object Resolve( params object[] args )
{
return m_Container.Resolve( m_Type, args );
}
但这是不完整的。Resolve()-方法不再是静态的(因为它需要两个实例字段),因此无法调用。所以这里的问题是
var callEx = Expression.Call( null, typeof( FuncFactory ).GetMethod( "Resolve" ), argsArray );
我想我需要一个对“this”的引用,而不是将null作为第一个参数传递。如何做到这一点?第一个问题是
Func
不存在-您需要分别编码到Func
,Func
,Func
,Func
现在;我理解代码,但我不确定您试图解决的场景是什么。。。你能澄清一下吗?也许有更好的选择
如果它像听起来一样复杂,那么定制的表达式
可能是最合适的选择(远比Reflection.Emit
简单)
例如,这是有效的
static Delegate MissingFunc(Type result, params Type[] args)
{
int i = 0;
var param = Array.ConvertAll(args,
arg => Expression.Parameter(arg, "arg" + i++));
var asObj = Array.ConvertAll(param,
p => Expression.Convert(p, typeof(object)));
var argsArray = Expression.NewArrayInit(typeof(object), asObj);
var body = Expression.Convert(Expression.Call(
null, typeof(Program).GetMethod("Resolve"),
argsArray), result);
return Expression.Lambda(body, param).Compile();
}
static void Main()
{
var func2 = MissingFunc(typeof(string), typeof(int), typeof(float));
}
public static object Resolve( params object[] args) {
throw new NotImplementedException();
}
我得说我不是100%确定我明白了你想要做的事情,但是让MissingMethod泛化不会让你解决问题的一半吗?或者这不是一个选项?哦,还有,我确实知道,你必须对它进行多次编码,以涵盖所有可能的Func泛型,但正如Marc所提到的,你无论如何都必须硬编码。通过编辑,我仍然不明白规则是什么。。。你希望它在[注入]时注入什么?为什么?谢谢你的回复。关于Func你是对的-我必须将接受的参数限制为四个。我想将代码与Resolve()方法(由IoC容器提供)解耦。相反,我希望能够创建小工厂(作为Func参数传递),通过间接使用IoC-container,使对象能够创建一种类型的多个实例。谢谢。。。我不熟悉表达。您能告诉我如何使Resolve()成为签名为“object Resolve(Type,params object)”的实例方法吗?我还是被卡住了:/对不起,我得去坐火车了;我可以在很大程度上详细阐述这个领域,但首先我要重复我的问题:这里的情况是什么?我至少可以用3种方法来处理这个问题(其中没有一种是Reflection.Emit)。。。如果它是一个实例方法。。。这是一个什么样的例子?也许你可以展示一点半完整的。如果你还不确定的话,可以随意取消这个标记作为答案——我不会生气的。只有当你对问题的解决感到满意时才将其标记为完成(我不确定它是…)我接受了你的答案,因为我确信它为我提供了有用的信息:)我只需要找出如何用表达式调用实例方法“object Resolve(Type,params object)”。我编辑了我的帖子-希望它能澄清我想做什么。。。
private Delegate CreateDelegate( Type returnType, Type[] parameterTypes )
{
m_Type = returnType;
var i = 0;
var param = Array.ConvertAll( parameterTypes, arg => Expression.Parameter( arg, "arg" + i++ ) );
var asObj = Array.ConvertAll( param, p => Expression.Convert( p, typeof( object ) ) );
var argsArray = Expression.NewArrayInit( typeof( object ), asObj );
var callEx = Expression.Call( null, typeof( FuncFactory ).GetMethod( "Resolve" ), argsArray );
var body = Expression.Convert( callEx, returnType );
var ret = Expression.Lambda( body, param ).Compile();
return ret;
}
private readonly Container m_Container;
private Type m_Type;
public object Resolve( params object[] args )
{
return m_Container.Resolve( m_Type, args );
}
var callEx = Expression.Call( null, typeof( FuncFactory ).GetMethod( "Resolve" ), argsArray );
static Delegate MissingFunc(Type result, params Type[] args)
{
int i = 0;
var param = Array.ConvertAll(args,
arg => Expression.Parameter(arg, "arg" + i++));
var asObj = Array.ConvertAll(param,
p => Expression.Convert(p, typeof(object)));
var argsArray = Expression.NewArrayInit(typeof(object), asObj);
var body = Expression.Convert(Expression.Call(
null, typeof(Program).GetMethod("Resolve"),
argsArray), result);
return Expression.Lambda(body, param).Compile();
}
static void Main()
{
var func2 = MissingFunc(typeof(string), typeof(int), typeof(float));
}
public static object Resolve( params object[] args) {
throw new NotImplementedException();
}