重构对 Dictionary.Value 的安全访问



我的目标是重构对Dictionary.Value的安全访问。
我有一个具有动态属性的 Json,所以我将其解析为Dictionary<string, string>~x9000 项:

var values = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(json);

尝试将其映射到业务对象,例如:

foreach (var item in values)
{
var temp = new BuissnessObject();

string idString, nameString, typeString, address1String, address2String,
address3String, cityString, postalCodeString, phoneNumberString,
openAfter8pmString, openOnSundayString, parkingString
// + 25 lines of string equivalent of BuissnessObject properties.
;
if (item.TryGetValue("id", out idString)) temp.id = idString;
if (item.TryGetValue("name", out nameString)) temp.name = nameString;
if (item.TryGetValue("type", out typeString)) temp.type = typeString;
if (item.TryGetValue("address1", out address1String)) temp.address1 = address1String;
if (item.TryGetValue("address2", out address2String)) temp.address2 = address2String;
if (item.TryGetValue("address3", out address3String)) temp.address3 = address3String;
if (item.TryGetValue("city", out cityString)) temp.city = cityString;
if (item.TryGetValue("postalCode", out postalCodeString)) temp.postalCode = postalCodeString;
if (item.TryGetValue("phoneNumber", out phoneNumberString)) temp.phoneNumber = phoneNumberString;

if (item.TryGetValue("openAfter8pm", out openAfter8pmString))
temp.openAfter8pm = bool.Parse(openAfter8pmString);
if (item.TryGetValue("openOnSunday", out openOnSundayString))
temp.openOnSunday = bool.Parse(openOnSundayString);
if (item.TryGetValue("parking", out parkingString))
temp.parking = bool.Parse(parkingString);
if (item.TryGetValue("reception", out receptionString))
temp.reception = bool.Parse(receptionString);
// ....

// Block Dynamic properties
temp.exceptionalDays = new List<DateTime>();
foreach (var k in item)
{   // Exemple: Key = exceptionalDay_YYYY_mm_dd ;  Value = True
if (k.Key.StartsWith("exceptionalDay") && bool.Parse(k.Value))
{
var dateRaw = k.Key.Split('_').Skip(1).ToArray();
if (dateRaw.Count() == 3)
{
var date = new DateTime(int.Parse(dateRaw[0]), int.Parse(dateRaw[1]), int.Parse(dateRaw[2]));
temp.exceptionalDays.Add(date);
}
}
}

result.Add(temp);
}

我正在寻找一种更好的方法来映射这两个实体。要么我反序列化两次:1rst 用于非动态属性忽略动态属性,然后仅用于动态属性。 或者我找到了一种缩短映射的方法,例如:

private static T GetSafe<T>(Dictionary<string, string> item, string key)
{
if (item.TryGetValue(key, out string value))
{
var converter = TypeDescriptor.GetConverter(typeof(T));
if (converter != null)
{
return (T)converter.ConvertFromString(value);
}
// Impossible to convert value of key {} - with value ={} for  type={}
throw new Exception(String.Format("Impossible de convertir la valeur de {0} - avec la valeur {1} !", key,value, typeof(T).FullName));
}
else
{
//Impossible de load the value of key {} - this key doesn't exist
throw new Exception(String.Format("Impossible de charger la valeur de {0} - Cette clé n'existe pas !", key));
}
throw new NotImplementedException();
}

以及一种循环 BuissnessObject 属性的方法,expt 用于列表中的属性。

如何获取 Burought BuissnessObject 属性名称?

您可以使用反射。给定类 BuissnessObject:

class BuissnessObject
{
public String Foo { get; set; }
public String Bar { get; set; }
public override string ToString()
{
return $"Foo : {Foo}, Bar : {Bar}";
}
}

而这个小帮手:

private static PropertyInfo[] GetProperties(object obj)
{
return obj.GetType().GetProperties();
}

您可以使用以下代码:

var businessObject = new BuissnessObject();
var dic = new Dictionary<string, string>()
{
{"Foo", "value1" },
{"Bar", "value2" },
};
// Get property array
var properties = GetProperties(businessObject);
foreach (var p in properties)
{
string name = p.Name;
// Skip what you want to skip
if(myListOfIgnoredProp.Contains(name))
continue;
// Feed what you want to feed
if (dic.TryGetValue(name, out var value))
{
if(p.PropertyType == typeof(string))
p.SetValue(businessObject, value);
else if (p.PropertyType == typeof(bool))
p.SetValue(businessObject, bool.Parse(value));
//And so on...
}
}

如果您致电businessObject.ToString(),您将获得:

Foo : 值 1, 柱线 : 值 2

最新更新