寻找一种更简洁的方法将C#setter放入词典<&燃气轮机;用于映射
这是我正在处理的更大一部分代码的表示,这是一个映射器。最初它是作为一个大的寻找一种更简洁的方法将C#setter放入词典<&燃气轮机;用于映射,c#,.net,reflection,C#,.net,Reflection,这是我正在处理的更大一部分代码的表示,这是一个映射器。最初它是作为一个大的switch语句编写的,但我更喜欢将映射作为一个表,而不是一个长的switch 我的第一次传球看起来像这样(来自LINQPad): 我真的不想在调用中作为带完全反射的字符串执行: { "one", "One" }, // No { "one", nameof(Foobar.One) }, // Real
switch
语句编写的,但我更喜欢将映射作为一个表,而不是一个长的switch
我的第一次传球看起来像这样(来自LINQPad):
我真的不想在调用中作为带完全反射的字符串执行:
{ "one", "One" }, // No
{ "one", nameof(Foobar.One) }, // Really, just no.
我似乎记得有一种更简洁的方法可以做到这一点,但我的谷歌fu让我失望。通过将签名更改为Dictionary
,然后执行以下操作,我可以更简洁地找到getter:
{ "one", f.One } // The getter, not the setter.
但这并不能让我成为二传手。想法?您可以这样定义映射:
Mapping<Foobar, decimal> foobarMapping = new Mapping<Foobar, decimal>
{
{ "one", f => f.One },
{ "double", f => f.Two },
{ "tricycle", f => f.Three },
};
public class Foobar
{
public decimal One { get; set; }
public decimal Two { get; set; }
public decimal Three { get; set; }
}
void Main()
{
Foobar obj = new Foobar();
obj.One = 100M;
foobarMapping[obj, "one"].Dump();
foobarMapping[obj, "tricycle"] = 400M;
obj.Three.Dump();
}
class Mapping<TFrom, TTo>: IEnumerable<KeyValuePair<string, PropertyInfo>>
{
Dictionary<string, PropertyInfo> mapping = new Dictionary<string, PropertyInfo>();
public void Add(string name, Expression<Func<TFrom, TTo>> mappingFunction) =>
mapping.Add(name, (PropertyInfo)((MemberExpression)mappingFunction.Body).Member);
public TTo this[TFrom from, string key]
{
get => (TTo)mapping[key].GetValue(from);
set => mapping[key].SetValue(from, value);
}
public IEnumerator<KeyValuePair<string, PropertyInfo>> GetEnumerator() =>
mapping.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
您编写的内容看起来几乎像一个索引器,或者尝试在不使用
dynamic
或继承DynamicObject
的情况下使用动态调用。您可以使用x[“三轮车”]=100M
或x.tricycle=100M
。这两种方法在性能上都比操作字典便宜。您可以使用类似于(action)typeof(Foobar).GetProperty(“One”).SetMethod.CreateDelegate(typeof(action))
的设置程序,但它并不更加精确
{ "one", f.One } // The getter, not the setter.
Mapping<Foobar, decimal> foobarMapping = new Mapping<Foobar, decimal>
{
{ "one", f => f.One },
{ "double", f => f.Two },
{ "tricycle", f => f.Three },
};
public class Foobar
{
public decimal One { get; set; }
public decimal Two { get; set; }
public decimal Three { get; set; }
}
void Main()
{
Foobar obj = new Foobar();
obj.One = 100M;
foobarMapping[obj, "one"].Dump();
foobarMapping[obj, "tricycle"] = 400M;
obj.Three.Dump();
}
class Mapping<TFrom, TTo>: IEnumerable<KeyValuePair<string, PropertyInfo>>
{
Dictionary<string, PropertyInfo> mapping = new Dictionary<string, PropertyInfo>();
public void Add(string name, Expression<Func<TFrom, TTo>> mappingFunction) =>
mapping.Add(name, (PropertyInfo)((MemberExpression)mappingFunction.Body).Member);
public TTo this[TFrom from, string key]
{
get => (TTo)mapping[key].GetValue(from);
set => mapping[key].SetValue(from, value);
}
public IEnumerator<KeyValuePair<string, PropertyInfo>> GetEnumerator() =>
mapping.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
100
400