Сократите код, открыв словарь с помощью if - PullRequest
0 голосов
/ 15 февраля 2019

У меня есть следующий код

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 голосов
/ 15 февраля 2019

Предполагая (учитывая строчные имена для полей 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 со свойством.

0 голосов
/ 15 февраля 2019

Использование локальной функции:

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}");
}

Гораздо короче

0 голосов
/ 15 февраля 2019
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);
0 голосов
/ 15 февраля 2019

Если ваш объект имеет ПОЛЯ, а не СВОЙСТВА, вы можете использовать просто 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
0 голосов
/ 15 февраля 2019

Вы всегда можете сделать что-то подобное.Начать более многословно, но если у вас много свойств, это может окупиться:

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...