使用if访问Dictionary来缩短代码

时间:2019-02-15 10:33:05

标签: c# dictionary if-statement

我有以下代码

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;

5 个答案:

答案 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字段为小写名称,field1field2field3实际上是字段而不是属性,则可以编写局部函数简化代码如下:

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