C# 如何使用表达式为索引器设置属性值?
我目前一直在将值设置到传递到以下函数的索引器表达式中:C# 如何使用表达式为索引器设置属性值?,c#,reflection,expression,C#,Reflection,Expression,我目前一直在将值设置到传递到以下函数的索引器表达式中: private static void SetPropertyValue(此T目标,表达式memberLamda,TValue值) { var memberSelectorExpression=memberLamda.Body作为MemberExpression; if(memberSelectorExpression!=null) { var property=memberSelectorExpression.Member作为Proper
private static void SetPropertyValue(此T目标,表达式memberLamda,TValue值)
{
var memberSelectorExpression=memberLamda.Body作为MemberExpression;
if(memberSelectorExpression!=null)
{
var property=memberSelectorExpression.Member作为PropertyInfo;
if(属性!=null)
{
SetValue(target,value,null);
回来
}
}
}
我有以下课程
类实体
{
公共对象[字符串名称]
{
获取{/**/}
集合{/**/}
}
}
当我现在使用以下值调用前面定义的函数时,我只得到对backingget\u Item()
方法的引用:
var实体=新实体();
// ...
SetPropertyValue(实体,x=>x[memberName],值);
有没有人给我一个提示,如何解决这个问题?任何想法都会有帮助
非常感谢大家…我想我看到了你们在尝试什么-一个适用于常规和索引属性的
SetPropertyValue
扩展。在这种情况下,您需要确定传入的表达式中引用的类型,以确定如何调用SetValue
:
public static void SetPropertyValue<T, TValue>(this T target, Expression<Func<T,TValue>> memberFn, TValue value) {
var b = memberFn.Body;
if (b is MethodCallExpression bc && bc.Method.IsSpecialName && bc.Method.Name.StartsWith("get_")) {
var PI = typeof(T).GetProperty(bc.Method.Name.Substring(4));
PI.SetValue(target, value, bc.Arguments.Select(a => a.Evaluate<object>()).ToArray());
}
else if (b is MemberExpression bm) {
var pi = bm.Member;
pi.SetValue(target, value);
}
}
我想这可能(不确定)与我的一个老问题有关:你认为x[membername]=value
有效吗?什么是membername
?想想x[membername]
意味着什么。。。Func
的类型参数代表什么?这正是我想要实现的。我会试试并给你反馈。#哇。。。谢谢它工作得很好。但是我认识到,这种反射逻辑并不是真正必要的,因为我手头有所有的选项来显式地使用setter操作,这取决于输入。因此,我也在不使用反射的情况下实现了性能改进。@MacX在避免反射方面非常出色-总是最好使用非反射工具。我检查了一下,似乎C#规范指定了一个项目的方法和属性的名称,所以直接使用项
可能是安全的。
public static void SetPropertyValue<T, TValue>(this T target, Expression<Func<T,TValue>> memberFn, TValue value) {
var b = memberFn.Body;
if (b is MethodCallExpression bc && bc.Method.IsSpecialName) {
var PI = typeof(T).GetProperties().First(pi => bc.Method.Name.Contains(pi.Name));
PI.SetValue(target, value, bc.Arguments.Select(a => a.Evaluate<object>()).ToArray());
}
else if (b is MemberExpression bm) {
var pi = bm.Member;
pi.SetValue(target, value);
}
}