是否可以向方法输入对象和第二个参数,以便可以使用第二个参数(不使用字符串和反射)来获取对象的属性并使用该属性来读取和写入值?
我在下面写了两种方法,我可以使用,但每种方法都有缺点。第一个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");
}
答案 0 :(得分:1)
我之前做过类似的事情。这是一个例子:
public void SetValue<T, TP>(T obj, Expression<Func<T, TP>> action, TP value) where T : class
{
var member = action.Body is UnaryExpression
? ((MemberExpression)((UnaryExpression)action.Body).Operand)
: (action.Body is MethodCallExpression
? ((MemberExpression)((MethodCallExpression)action.Body).Object)
: (MemberExpression)action.Body);
var key = member?.Member.Name;
typeof(T).GetProperty(key).SetValue(obj, value);
}
你这样称呼它。
SetValue<User>(x=> x.UserName, "Admin");