C# 使用附加参数编译LambdaExpression

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

我正在尝试获取MethodInfo对象并对其调用Invoke()。以下是我迄今为止所尝试的:

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 to
object

将值框起来,谢谢您的深刻回答。不幸的是,我不能直接调用
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);