На мой взгляд, у вас есть несколько вариантов, в зависимости от ваших навыков, способа, которым вам разрешено менять текущие POCO или другие классы:
- Если вы должны использовать словарь, создайте аналогичный словарь, который сопоставляет «0D» и т. Д. С именами OneDay. Переберите словарь и назначьте, используя простое отражение.
- Если вы можете изменить способ чтения данных, прочитайте словарь с помощью OneDay и т. Д. Вместо «0D», который применим только к внешнему приложению.
- Создайте атрибут,
LegacyKeyAttribute
, увеличьте ваши получатели / установщики POCO этим атрибутом. Теперь это становится тривиальным: просматривайте свойства POCO, чтобы найти правильное свойство для вашего текущего унаследованного ключа.
Последний вариант требует немного большего понимания C #, чем многие обычные программисты знают: написание и использование атрибутов и рефлексии. Однако, в конце концов, это самое чистое и простое решение (я постараюсь привести пример).
ОБНОВЛЕНИЕ: вот небольшой пример. Между тем, было опубликовано много предложений по улучшению, но ни одно из них по-прежнему не использует атрибуты, в то время как ваш случай кажется идеальным. Зачем? Я считаю, что это создает наименьшую нагрузку на существующий код и делает чтение и понимание вашего кода еще проще.
Использование:
// any price:
Prices prices = new Prices();
prices.SetPriceByLegacyName("0D", 1.2345M);
// or, your loop becomes a bit easier:
SetPricesValues(IDictionary<string, decimal> pricesDictionary)
{
foreach(string key in pricesDictionary.Keys)
{
// assuming "this" is of type Prices (you didn't specify)
this.SetPriceByLegacyName(key, pricesDictionary[key]);
}
}
Реализация:
// the simplest attribute class is enough for you:
[AttributeUsage(AttributeTargets.Property)]
public class LegacyNameAttribute : Attribute
{
public string Name { get; set; }
public LegacyNameAttribute(string name)
{
this.Name = name;
}
}
// your Prices POCO class becomes easier to read
public class Prices
{
[LegacyName("0D")] public decimal Today { get; set; }
[LegacyName("1D")] public decimal OneDay { get; set; }
[LegacyName("6D")] public decimal SixDay { get; set; }
[LegacyName("10D")] public decimal TenDay { get; set; }
[LegacyName("12D")] public decimal TwelveDay { get; set; }
[LegacyName("1DA")] public decimal OneDayAdjusted { get; set; }
[LegacyName("6DA")] public decimal SixDayAdjusted { get; set; }
[LegacyName("10DA")] public decimal TenDayAdjusted { get; set; }
[LegacyName("100DA")] public decimal OneHundredDayAdjusted { get; set; }
}
// an extension method to ease the implementation:
public static class PricesExtensions
{
public static void SetPriceByLegacyName(this Prices price, string name, decimal value)
{
if (price == null)
throw new ArgumentException("Price cannot be null");
foreach (PropertyInfo prop in price.GetType().GetProperties())
{
LegacyNameAttribute legNameAttribute = (LegacyNameAttribute)
Attribute.GetCustomAttribute(prop, typeof(LegacyNameAttribute));
// set the property if the attribute matches
if (legNameAttribute != null && legNameAttribute.Name == name)
{
prop.SetValue(price, value, null);
break; // nothing more to do
}
}
}
}
Вот и все, что нужно сделать. Даже со всеми добавленными строками вполне может быть, что общее количество строк становится меньше. Но что более важно, его становится проще поддерживать и использовать.