C# 使用附加参数编译LambdaExpression
我正在尝试获取MethodInfo对象并对其调用Invoke()。以下是我迄今为止所尝试的:C# 使用附加参数编译LambdaExpression,c#,lambda,expression,C#,Lambda,Expression,我正在尝试获取MethodInfo对象并对其调用Invoke()。以下是我迄今为止所尝试的: public class ContactCustomFieldsFacet { public Dictionary<string, string> Fields { get; set; } = new Dictionary<string, string>(); } public static class FacetExtensions { public sta
public class ContactCustomFieldsFacet
{
public Dictionary<string, string> Fields { get; set; } = new Dictionary<string, string>();
}
public static class FacetExtensions
{
public static Func<ContactCustomFieldsFacet, object> Compile(string body)
{
ParameterExpression prm = Expression.Parameter(typeof(ContactCustomFieldsFacet), typeof(ContactCustomFieldsFacet).Name);
LambdaExpression exp = DynamicExpressionParser.ParseLambda(new[] { prm }, typeof(object), body);
return (Func<ContactCustomFieldsFacet, object>)exp.Compile();
}
}
var lambda = FacetExtensions.Compile($"ContactCustomFieldsFacet.Fields[\"test\"]");
var propertyMethod = lambda.Method;
// No control over the below code - it's called by a third party library
ContactCustomFieldsFacet facet = GetFacet();
propertyMethod.Invoke(null, new [] { facet }); // System.ArgumentException: MethodInfo must be a runtime MethodInfo object.
公共类联系人CustomFieldsFacet
{
公共字典字段{get;set;}=new Dictionary();
}
公共静态类扩展
{
公共静态Func编译(字符串体)
{
ParameterExpression prm=表达式.参数(类型of(ContactCustomFieldsFacet),类型of(ContactCustomFieldsFacet).Name);
LambdaExpression exp=DynamicExpressionParser.ParseLambda(new[]{prm},typeof(object),body);
返回(Func)exp.Compile();
}
}
var lambda=FaceExtensions.Compile($“ContactCustomFieldsFacet.Fields[\“test\”]);
var propertyMethod=lambda.Method;
//无法控制以下代码-它由第三方库调用
ContactCustomFieldsFacet facet=GetFacet();
propertyMethod.Invoke(null,new[]{facet});//System.ArgumentException:MethodInfo必须是运行时MethodInfo对象。
本质上,我希望能够动态创建一个表达式,该表达式具有针对该实例硬编码的ContactCustomFieldsFacet.Fields
字典索引字段。
我意识到我可能走错了方向,所以任何指点都会很感激
.NET小提琴:
编辑
多亏了Corey,我更新了代码,但仍然遇到类似的问题
.NET Fiddle:定位要调用的方法相当简单。困难的部分是找出要调用的方法的名称。有时,最简单的方法是创建一个表达式,并查看编译器是如何将其组合在一起的 例如:
Expression<Func<Dictionary<string, string>, string>> expr = d => d["test"];
调用该方法将获得一个Func
,该函数返回特定键的值,该值在构建Func
时设置。例如:
var fnGetTest = MakeAccessor("test");
var value = fnGetTest(someFacetInstance);
这一切都假设字典存储引用类型-string可以正常工作。如果它是一种值类型(例如int),您需要通过Convert
ing toobject
将值框起来,谢谢您的深刻回答。不幸的是,我不能直接调用fngetest(someFacetInstance)
,因为我需要将它传递给第三方DLL来调用。有什么想法吗?问题更新。啊,我错过了第三方库试图调用方法的消息Lambda.Compile
返回不能以这种方式使用的委托。您可能会被经典的运行时发射(抖动)所困扰。也许是罗斯林。需要明确的是,func(…)
和func.Invoke(…)
起作用,func.Method.Invoke(…)
不起作用。您对调用中的null
对象参数有多确定?如果它确实执行了func.Method.Invoke(func.Target,…)
,那么有一个简单的方法来执行。任何使用DynamicMethod
或类似方法(包括LINQ表达式和直接发射)的操作在此步骤中将失败。
var fnGetTest = MakeAccessor("test");
var value = fnGetTest(someFacetInstance);