C# 重构对Dictionary.Value的安全访问
我的目标是重构对Dictionary.Value的安全访问。C# 重构对Dictionary.Value的安全访问,c#,C#,我的目标是重构对Dictionary.Value的安全访问。 我有一个具有动态属性的Json,因此我将其解析为字典~x9000项: var values = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(json); var values=JsonConvert.DeserializeObject(json); 尝试将其映射到buissness对象,如: foreach (v
我有一个具有动态属性的Json,因此我将其解析为
字典
~x9000项:
var values = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(json);
var values=JsonConvert.DeserializeObject(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);
}
foreach(值中的变量项)
{
var temp=新建BuissnessObject();
字符串ID字符串、名称字符串、类型字符串、地址1字符串、地址2字符串、,
address3String、cityString、postalCodeString、phoneNumberString、,
openAfter8pmString、openOnSundayString、parkingString
//+25行字符串,相当于BuissnessObject属性。
;
如果(item.TryGetValue(“id”,out idString))temp.id=idString;
如果(item.TryGetValue(“name”,out nameString))temp.name=nameString;
如果(item.TryGetValue(“type”,out-typeString))temp.type=typeString;
如果(item.TryGetValue(“address1”,out address1String))临时地址1=address1String;
如果(item.TryGetValue(“address2”,out address2字符串))临时地址2=address2字符串;
如果(item.TryGetValue(“address3”,out address3String))临时地址3=address3String;
如果(项目TryGetValue(“城市”,外城市字符串))温度城市=城市字符串;
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(项TryGetValue(“openOnSunday”,out openOnSundayString))
temp.openOnSunday=bool.Parse(openOnSundayString);
if(项目TryGetValue(“停车”,外停车管柱))
临时停车=布尔解析(停车串);
if(项目TryGetValue(“接收”,输出接收字符串))
临时接收=布尔解析(接收字符串);
// ....
//块动态特性
temp.exceptionalDays=新列表();
foreach(项目中的var k)
{//example:Key=exceptionalDay\u YYYY\u mm\u 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]);
临时例外天数添加(日期);
}
}
}
结果。添加(温度);
}
我正在寻找一种更好的方法来映射这两个实体。或者我反序列化两次:第一次是非动力学性质,忽略动力学性质,然后是动力学性质。
或者我找到了一种缩短映射的方法,如:
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();
}
private static T GetSafe(字典项、字符串键)
{
if(item.TryGetValue(键,输出字符串值))
{
var converter=TypeDescriptor.GetConverter(typeof(T));
if(转换器!=null)
{
return(T)converter.ConvertFromString(值);
}
//无法转换类型为{}的值为{}的键{}-的值
抛出新异常(String.Format(“不可能的de convertir la valeur de{0}-avec la valeur{1}!”,键,值,typeof(T.FullName));
}
其他的
{
//无法卸载键{}的值-此键不存在
抛出新的异常(String.Format(“不可能的de charger la valeur de{0}-Cette clén'existe pas!”,key));
}
抛出新的NotImplementedException();
}
以及一种循环BuissnessObject属性的方法,该属性对于列表中的一个对象是exept
如何处理每个trought 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...
}
}
var businessObject=new businessObject();
var dic=新字典()
{
{“Foo”,“value1”},
{“Bar”,“value2”},
};
//获取属性数组
var properties=GetProperties(businessObject);
foreach(属性中的var p)
{
字符串名称=p.名称;
//跳过你想跳过的
if(myListOfIgnoredProp.Contains(name))
继续;
//喂你想喂的东西
if(dic.TryGetValue(名称,输出var值))
{
if(p.PropertyType==typeof(string))
p、 SetValue(businessObject,value);
else if(p.PropertyType==typeof(bool))
p、 SetValue(businessObject,bool.Parse(value));
//等等。。。
}
}
如果调用businessObject.ToString()
,您将得到:
Foo:value1,Bar:value2
为什么要将其解析为
字典
,而不仅仅是一个常规的列表
?事实上,您可以在//块动态属性
中看到,一些信息是使用名称而不是json中的值发送的。例如,当他们一天不工作时,会发送“NotWorking\u 2018\u 05\u 04”:“True”。因此,我从一个角度使用这个解决方案,真实也有点重要,因为当他们想表明他们将在无人执行的一天工作时,他们会发送“NotWorking\u 2018\u 05\u 04”:“false”。以表明他们会工作。。我无法控制这一切。用一个简单的开关取代我的GetSafe
真不错!这是我的一票。我会让这个问题持续一周,这样其他人可以在选择获胜者之前尝试回答。但是谢谢你