我的目标是重构对Dictionary.Value的安全访问
我有一个具有动态属性的Json,因此我将其解析为Dictionary<string, string>
~x9000项:
var values = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(json);
尝试将此映射到buissness对象,如:
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);
}
我&#39;我正在寻找一种更好的方法来映射这两个实体。要么我反序列化两次:第一次是非动态属性忽略动态属性,然后只是动态。 或者我找到了缩短映射的方法,如:
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属性的方法是对List中的那个进行循环。
如何预测BuissnessObject属性名称?
答案 0 :(得分:2)
你可以使用反思。鉴于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...
}
}
< p>如果你致电businessObject.ToString()
,你将获得: Foo:value1,Bar:value2