gpt4 book ai didi

c# - 创建访问属性的表达式

转载 作者:太空狗 更新时间:2023-10-30 01:12:37 24 4
gpt4 key购买 nike

我有以下类(class):

internal class Sensors
{
public JsonSensor<double> IOPcwFlSpr { get; set; } = new JsonSensor<double>();
}

internal class JsonSensor<TType> : IJsonSensor
{
public TType Value { get; set; }
}

我想构建一个检索该属性的表达式。

private static readonly List < PropertyInfo > Properties;

static SensorFactory() {
Properties = typeof(Json.Sensors).GetProperties().ToList();
}

public void Test(Json.Sensors jsonUpdate) {
foreach(var property in Properties) {
var getterMethodInfo = property.GetGetMethod();
var parameterExpression = Expression.Parameter(jsonUpdate.GetType(), "x");
var callExpression = Expression.Call(parameterExpression, getterMethodInfo);

var lambda = Expression.Lambda < Func < JsonSensor < double >>> (callExpression);
var r = lambda.Compile().Invoke();
}
}

抛出:

System.InvalidOperationException : variable 'x' of type 'Sensors' referenced from scope '', but it is not defined

这是有道理的,因为我从未将“x”分配给实际对象。如何添加“参数对象”?

最佳答案

像这样使用表达式树的关键是使用参数(ParameterExpression)编译它一次,创建一个Func<Foo,Bar>它接受您的输入 ( Foo ) 并返回您想要的任何内容 ( Bar )。然后使用不同的对象多次重用已编译的委托(delegate)。

我看不到确切你想做什么,但我猜它会是这样的:

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;


namespace Json
{
static class P
{
static void Main()
{
var obj = new Sensors { IOPcwFlSpr = { Value = 42.5 }, Whatever = { Value = 9 } };

foreach(var pair in SomeUtil.GetSensors(obj))
{
Console.WriteLine($"{pair.Name}: {pair.Value}");
}
}
}

public class Sensors
{
public JsonSensor<double> IOPcwFlSpr { get; set; } = new JsonSensor<double>();
public JsonSensor<int> Whatever { get; set; } = new JsonSensor<int>();
}

public interface IJsonSensor
{
public string Value { get; }
}
public class JsonSensor<TType> : IJsonSensor
{
public TType Value { get; set; }
string IJsonSensor.Value => Convert.ToString(Value);
}

public static class SomeUtil
{
private static readonly (string name, Func<Sensors, IJsonSensor> accessor)[] s_accessors
= Array.ConvertAll(
typeof(Sensors).GetProperties(BindingFlags.Instance | BindingFlags.Public),
prop => (prop.Name, Compile(prop)));

public static IEnumerable<(string Name, string Value)> GetSensors(Sensors obj)
{
foreach (var acc in s_accessors)
yield return (acc.name, acc.accessor(obj).Value);
}
private static Func<Sensors, IJsonSensor> Compile(PropertyInfo property)
{
var parameterExpression = Expression.Parameter(typeof(Json.Sensors), "x");
Expression body = Expression.Property(parameterExpression, property);
body = Expression.Convert(body, typeof(IJsonSensor));
var lambda = Expression.Lambda<Func<Json.Sensors, IJsonSensor>>(body, parameterExpression);
return lambda.Compile();
}
}
}

关于c# - 创建访问属性的表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57588068/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com