Reputation: 2050
I have the following code
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"];
}
which has 4 lines for a potential assignment. I'm wondering if there is a way to write it shorter.
I've tried the ternary operator which makes one line but it's harder to read.
resultObject.field1 = changesDictionary.ContainsKey("field1") ? changesDictionary["field1"] : resultObject.field1;
Upvotes: 1
Views: 164
Reputation: 38179
Using a local function:
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);
Price to pay = readability--
Line count = 11 instead of 13
Using a local function + reflection (provided fieldx are public properties):
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");
Price to pay = performance--
Line count = 12 instead of 13, but if you have 20 fields to update:
for (int i = 1; i <= 20; i++)
{
SetField($"field{i}");
}
Much shorter
Upvotes: 1
Reputation: 109792
Assuming (given the lowercase names for the field
fields) that field1
, field2
and field3
are actually fields rather than properties, then you can write a local function to simplify the code as follows:
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");
Note that will NOT work if field1
etc are actually properties, because of course you can't use ref
with a property.
Upvotes: 0
Reputation: 42330
You could always do something like this. It's more verbose to start, but if you have lots of properties then it might pay off:
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);
}
}
Another option is something like this:
// 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);
Otherwise, if you're prepared to change your style slightly, you can do this:
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;
Upvotes: 4
Reputation: 2879
If your object has FIELDS not PROPERTIES, u can use just TryGetValue to field like this
changesDictionary.TryGetValue(nameof(ResultObject.field1), out resultObject.field1);
full example:
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;
}
}
}
output:
q1
q2
q3
q4
Upvotes: -1
Reputation: 8207
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);
Upvotes: -1