【发布时间】:2017-12-06 09:18:05
【问题描述】:
是否可以在方法中输入一个对象和第二个参数,以便第二个参数可以用来(不使用字符串和反射)获取对象的a属性,并使用该属性来读写价值?
我在下面编写了两种可以使用的方法,但每种方法都有缺点。第一个 DoStuff 是类型安全的(“好”),但它需要三个参数(“坏”)。第二个需要两个参数(最佳),但它不是类型安全的(“坏”),因为它依赖于字符串来指定属性。也许有一些我没有想到的使用Expression 的解决方案?
背景:用例是我希望能够“扩展”任何对象的值(在我的情况下,我有来自多个对象存储库的对象列表,这些对象可能具有包含用户 ID 作为字符串的多个属性。另一个存储库包含用户,我想将有关用户的信息添加到以前存储库中的字符串中)
public class Foo
{
public string Bar {get; set;}
}
void Main()
{
var x = new Foo { Bar = "hello" };
Console.WriteLine(x.Bar); // prints "hello"
// the second paramter (Func<..>) gets the value, the third parameter Action<...>) sets the value
DoStuff(x, y => y.Bar, (z, val) => z.Bar = val);
Console.WriteLine(x.Bar); // prints "hello goodbye"
// just one parameter to get the property, but I would like this to be more type safe, preferably a Func
DoStuff2(x, nameof(x.Bar));
Console.WriteLine(x.Bar); // prints "hello goodbye again"
}
public void DoStuff<T>(
T obj,
Func<T, string> getProp,
Action<T, string> setProp)
{
var x = getProp(obj);
setProp(obj, x + " goodbye");
}
public void DoStuff2<T>(
T obj,
string propName)
{
var propInfo = typeof(T).GetProperty(propName);
var currValue = propInfo.GetValue(obj) as string;
propInfo.SetValue(obj, currValue + " again");
}
【问题讨论】:
-
您正在寻找
Expression<Func<T, object>>。您可以编译(.Compile())并调用它来获取值。 -
@john:使用
Expression<Func<T, object>>的DoStuff3会是什么样子?你会写它作为答案吗?或者你有链接吗?对我来说,Expersions 仍然有点混乱...... -
见here
-
@john:非常感谢!
标签: c# expression-trees func