Saw*_*wan 79 .net c# mapping dictionary idictionary
是否有任何优雅的快速方法将对象映射到字典,反之亦然?
IDictionary<string,object> a = new Dictionary<string,object>();
a["Id"]=1;
a["Name"]="Ahmad";
// .....
Run Code Online (Sandbox Code Playgroud)
变
SomeClass b = new SomeClass();
b.Id=1;
b.Name="Ahmad";
// ..........
Run Code Online (Sandbox Code Playgroud)
Mat*_*zer 162
在两种扩展方法中使用一些反射和泛型可以实现这一点.
是的,其他人做了大多数相同的解决方案,但这使用较少的反射,这在性能方面更具有可读性:
public static class ObjectExtensions
{
public static T ToObject<T>(this IDictionary<string, object> source)
where T : class, new()
{
var someObject = new T();
var someObjectType = someObject.GetType();
foreach (var item in source)
{
someObjectType
.GetProperty(item.Key)
.SetValue(someObject, item.Value, null);
}
return someObject;
}
public static IDictionary<string, object> AsDictionary(this object source, BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
{
return source.GetType().GetProperties(bindingAttr).ToDictionary
(
propInfo => propInfo.Name,
propInfo => propInfo.GetValue(source, null)
);
}
}
class A
{
public string Prop1
{
get;
set;
}
public int Prop2
{
get;
set;
}
}
class Program
{
static void Main(string[] args)
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
dictionary.Add("Prop1", "hello world!");
dictionary.Add("Prop2", 3893);
A someObject = dictionary.ToObject<A>();
IDictionary<string, object> objectBackToDictionary = someObject.AsDictionary();
}
}
Run Code Online (Sandbox Code Playgroud)
lea*_*tes 19
首先使用Newtonsoft将Dictionary转换为JSON字符串。
var json = JsonConvert.SerializeObject(advancedSettingsDictionary, Newtonsoft.Json.Formatting.Indented);
Run Code Online (Sandbox Code Playgroud)
然后将JSON字符串反序列化为您的对象
var myobject = JsonConvert.DeserializeObject<AOCAdvancedSettings>(json);
Run Code Online (Sandbox Code Playgroud)
And*_*ich 11
似乎反射只有帮助.我已经完成了将对象转换为字典的小例子,反之亦然:
[TestMethod]
public void DictionaryTest()
{
var item = new SomeCLass { Id = "1", Name = "name1" };
IDictionary<string, object> dict = ObjectToDictionary<SomeCLass>(item);
var obj = ObjectFromDictionary<SomeCLass>(dict);
}
private T ObjectFromDictionary<T>(IDictionary<string, object> dict)
where T : class
{
Type type = typeof(T);
T result = (T)Activator.CreateInstance(type);
foreach (var item in dict)
{
type.GetProperty(item.Key).SetValue(result, item.Value, null);
}
return result;
}
private IDictionary<string, object> ObjectToDictionary<T>(T item)
where T: class
{
Type myObjectType = item.GetType();
IDictionary<string, object> dict = new Dictionary<string, object>();
var indexer = new object[0];
PropertyInfo[] properties = myObjectType.GetProperties();
foreach (var info in properties)
{
var value = info.GetValue(item, indexer);
dict.Add(info.Name, value);
}
return dict;
}
Run Code Online (Sandbox Code Playgroud)
Tod*_*ier 10
我强烈推荐Castle DictionaryAdapter,这是该项目保存最好的秘密之一.您只需要定义一个具有所需属性的接口,并在一行代码中,适配器将生成一个实现,实例化它,并将其值与您传入的字典同步.我用它来强类型我的AppSettings in一个网络项目:
var appSettings =
new DictionaryAdapterFactory().GetAdapter<IAppSettings>(ConfigurationManager.AppSettings);
Run Code Online (Sandbox Code Playgroud)
请注意,我不需要创建一个实现IAppSettings的类 - 适配器即时执行.此外,虽然在这种情况下我只是阅读,理论上如果我在appSettings上设置属性值,适配器将使基础字典与这些更改保持同步.
我认为你应该使用反射。像这样的东西:
private T ConvertDictionaryTo<T>(IDictionary<string, object> dictionary) where T : new()
{
Type type = typeof (T);
T ret = new T();
foreach (var keyValue in dictionary)
{
type.GetProperty(keyValue.Key).SetValue(ret, keyValue.Value, null);
}
return ret;
}
Run Code Online (Sandbox Code Playgroud)
它获取你的字典并循环它并设置值。你应该让它变得更好,但这只是一个开始。你应该这样称呼它:
SomeClass someClass = ConvertDictionaryTo<SomeClass>(a);
Run Code Online (Sandbox Code Playgroud)
通过迭代属性,反射可以将您从对象带到字典.
换句话说,你必须在C#中使用动态的ExpandoObject(事实上,它已经从IDictionary继承了,所以已经为你完成了这个),除非你可以从中收集条目集合中的类型.字典不知何故.
所以,如果你在.NET 4.0中,请使用ExpandoObject,否则你需要做很多工作......
小智 5
基于 Mat\xc3\xadas Fidemraizer 的答案,这里是一个支持绑定到字符串以外的对象属性的版本。
\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace WebOpsApi.Shared.Helpers\n{\n public static class MappingExtension\n {\n public static T ToObject<T>(this IDictionary<string, object> source)\n where T : class, new()\n {\n var someObject = new T();\n var someObjectType = someObject.GetType();\n\n foreach (var item in source)\n {\n var key = char.ToUpper(item.Key[0]) + item.Key.Substring(1);\n var targetProperty = someObjectType.GetProperty(key);\n\n //edited this line\n if (targetProperty.PropertyType == item.Value.GetType())\n {\n targetProperty.SetValue(someObject, item.Value);\n }\n else\n {\n\n var parseMethod = targetProperty.PropertyType.GetMethod("TryParse",\n BindingFlags.Public | BindingFlags.Static, null,\n new[] {typeof (string), targetProperty.PropertyType.MakeByRefType()}, null);\n \n if (parseMethod != null)\n {\n var parameters = new[] { item.Value, null };\n var success = (bool)parseMethod.Invoke(null, parameters);\n if (success)\n {\n targetProperty.SetValue(someObject, parameters[1]);\n }\n\n }\n }\n }\n\n return someObject;\n }\n\n public static IDictionary<string, object> AsDictionary(this object source, BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)\n {\n return source.GetType().GetProperties(bindingAttr).ToDictionary\n (\n propInfo => propInfo.Name,\n propInfo => propInfo.GetValue(source, null)\n );\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
94555 次 |
| 最近记录: |