【发布时间】:2020-07-29 14:21:42
【问题描述】:
这是我正在处理的大量代码的表示,它是一个映射器。最初它被写成一个大的switch 语句,但我更喜欢将映射突出为一个表格,而不是一个很长很长的switch。
我的第一遍看起来像这样(来自 LINQPad):
Dictionary<string, Action<Foobar, decimal>> map
= new Dictionary<string, Action<Foobar, decimal>> {
{ "one", (f,d) => f.One = d },
{ "double", (f,d) => f.Two = d },
{ "tricycle", (f,d) => f.Three = d },
};
void Main()
{
Foobar obj = new Foobar();
decimal amount = 100M;
var x = map["one"];
x(obj, amount);
Console.WriteLine(obj.One); // Prints 100 as expected
}
public class Foobar
{
public decimal One { get; set; }
public decimal Two { get; set; }
public decimal Three { get; set; }
}
真正的Foobar 类很大,有很多属性,但它们都是同一类型:decimal。
我正在寻找一种更简洁的方式来表达上表。这很好:
{ "one", (f,d) => f.One = d }, // It works, but … can it be better?
我真的不想在调用中将其作为具有完整反射的字符串:
{ "one", "One" }, // No
{ "one", nameof(Foobar.One) }, // Really, just no.
我似乎记得有一种更简洁的方法可以做到这一点,但我的 Google-fu 让我失望了。我可以通过将签名更改为Dictionary<string, Func<Foobar, decimal>> 来更简洁地使用 getter,然后执行以下操作:
{ "one", f.One } // The getter, not the setter.
但这并没有让我进入 setter。想法?
【问题讨论】:
-
您写的内容看起来几乎像一个索引器,或者尝试使用动态调用而不使用
dynamic或从DynamicObject继承。您可以使用x["tricycle"]=100M或x.tricycle=100M。两者的性能都会比动作字典便宜 -
你可以用
(Action<Foobar, decimal>)typeof(Foobar).GetProperty("One").SetMethod.CreateDelegate(typeof(Action<Foobar, decimal>))之类的东西来获取setter,但这并不更简洁
标签: c# .net reflection