我有以下代码
Dictionary<string, string> changesDictionary = new Dictionary<string, string>();
if (changesDictionary.ContainsKey("field1"))
{
resultObject.field1 = changesDictionary["field1"];
}
if (changesDictionary.ContainsKey("field2"))
{
resultObject.field2 = changesDictionary["field2"];
}
if (changesDictionary.ContainsKey("field3"))
{
resultObject.field3 = changesDictionary["field3"];
}
,其中有4行用于潜在的分配。我想知道是否有一种写得更短的方法。
我已经尝试过只写一行的三元运算符,但是很难阅读。
resultObject.field1 = changesDictionary.ContainsKey("field1") ? changesDictionary["field1"] : resultObject.field1;
答案 0 :(得分:4)
您总是可以做这样的事情。开始时比较冗长,但是如果您有很多属性,那么它可能会有所回报:
var fields = new (string key, Action<ResultObject, string> setter)[]
{
("field1", (x, val) => x.field1 = val),
("field2", (x, val) => x.field2 = val),
("field3", (x, val) => x.field3 = val),
};
foreach (var (key, setter) in fields)
{
if (changesDictionary.TryGetValue(key, out var field))
{
setter(resultObject, field);
}
}
另一个选择是这样的:
// A local function which captures 'resultObject' and 'changesDictionary'
void Set(string key, Action<ResultObject, string> setter)
{
if (changesDictionary.TryGetValue(key, out var field))
{
setter(resultObject, field);
}
}
Set("field1", (x, val) => x.field1 = val);
Set("field2", (x, val) => x.field2 = val);
Set("field3", (x, val) => x.field3 = val);
否则,如果您准备稍微更改样式,则可以执行以下操作:
if (changesDictionary.TryGetValue("field1", out var field1)) resultObject.field1 = field1;
if (changesDictionary.TryGetValue("field2", out var field2)) resultObject.field2 = field2;
if (changesDictionary.TryGetValue("field3", out var field3)) resultObject.field1 = field3;
答案 1 :(得分:1)
使用局部功能:
void SetField(string fieldName, Action<string> updater)
{
if (changesDictionary.TryGetValue(fieldName, out string fieldValue))
{
updater(fieldValue);
}
}
SetField("field1", f => resultObject.field1 = f);
SetField("field2", f => resultObject.field2 = f);
SetField("field3", f => resultObject.field3 = f);
要付出的代价=可读性-
行数= 11而不是13
使用局部函数+反射(提供的fieldx是公共属性):
void SetField(string fieldName)
{
if (changesDictionary.TryGetValue(fieldName, out string fieldValue))
{
PropertyInfo propertyInfo = resultObject.GetType().GetProperty(fieldName);
propertyInfo.SetValue(resultObject, fieldValue);
}
}
SetField("field1");
SetField("field2");
SetField("field3");
要付出的代价=业绩-
行数= 12而不是13,但是如果您有20个字段需要更新:
for (int i = 1; i <= 20; i++)
{
SetField($"field{i}");
}
短得多
答案 2 :(得分:0)
假设field
字段为小写名称,field1
,field2
和field3
实际上是字段而不是属性,则可以编写局部函数简化代码如下:
Dictionary<string, string> changesDictionary = new Dictionary<string, string>();
void update(ref string field, string key)
{
if (changesDictionary.TryGetValue(key, out var value))
field = value;
}
update(ref resultObject.field1, "field1");
update(ref resultObject.field2, "field1");
update(ref resultObject.field3, "field1");
请注意,如果field1
等实际上是属性,则将不起作用,因为您当然不能将ref
与属性一起使用。
答案 3 :(得分:-1)
public static class DictionaryExtensions
{
public static TValue GetOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue)
{
if (dictionary.TryGetValue(key, out value))
return value;
return defaultValue;
}
}
. . .
resultObject.field1 = changesDictionary.GetOrDefault("field1", resultObject.field1);
resultObject.field2 = changesDictionary.GetOrDefault("field2", resultObject.field2);
resultObject.field3 = changesDictionary.GetOrDefault("field3", resultObject.field3);
答案 4 :(得分:-1)
如果您的对象具有FIELDS而不是PROPERTIES,则可以仅使用TryGetValue来进行字段
changesDictionary.TryGetValue(nameof(ResultObject.field1), out resultObject.field1);
完整示例:
using System;
using System.Collections.Generic;
namespace ConsoleApp27
{
internal class Program
{
private static void Main(string[] args)
{
var resultObject = new ResultObject();
var changesDictionary = new Dictionary<string, string>();
changesDictionary.Add(nameof(ResultObject.field1), "q1");
changesDictionary.Add(nameof(ResultObject.field2), "q2");
changesDictionary.Add(nameof(ResultObject.field3), "q3");
changesDictionary.Add(nameof(ResultObject.field4), "q4");
changesDictionary.TryGetValue(nameof(ResultObject.field1), out resultObject.field1);
changesDictionary.TryGetValue(nameof(ResultObject.field2), out resultObject.field2);
changesDictionary.TryGetValue(nameof(ResultObject.field3), out resultObject.field3);
changesDictionary.TryGetValue(nameof(ResultObject.field4), out resultObject.field4);
Console.WriteLine(resultObject.field1);
Console.WriteLine(resultObject.field2);
Console.WriteLine(resultObject.field3);
Console.WriteLine(resultObject.field4);
Console.ReadLine();
}
public class ResultObject
{
public string field1;
public string field2;
public string field3;
public string field4;
}
}
}
输出:
q1
q2
q3
q4