Tôi đang tìm cách tổng quát hơn/"chuẩn" để khởi tạo đối tượng của một kiểu T từ tập hợp các cặp chuỗi, đối tượng. Đối với tôi có vẻ như có một số cách nổi tiếng để làm điều đó nhưng tôi không thể tìm thấy nó, vì vậy tôi đưa ra đoạn mã này. Có ai biết điều gì tốt hơn không? Khởi tạo đối tượng kiểu T từ điển <string, object>
// usage
public class test
{
public int field1;
public string field2;
public bool field3;
public string[] field4;
public IDictionary<string,object> field5 { get; set; }
public static IDictionary<string,object> dynamic()
{
return new Dictionary<string,object>{
{ "field1", 2 },
{ "field2", "string" },
{ "field3", true },
{ "field4", new[] { "id3", "id4", "id5" } },
{ "field5", new Dictionary<string,object>{ { "id1", "" } } }
};
}
}
...
var r = new dynamic_data_serializer<test>().create(test.dynamic());
...
//
public class dynamic_data_serializer<T>
{
public T create(object obj)
{
var result = default(T);
if (obj == null)
return result;
var ttype = typeof(T);
var objtype = obj.GetType();
if (ttype.IsAssignableFrom(objtype)) {
result = (T)obj;
return result;
}
if (ttype.IsClass) { // custom classes, array, dictionary, etc.
result = Activator.CreateInstance<T>();
if (objtype == typeof(IDictionary<string,object>) ||
objtype == typeof(Dictionary<string,object>)) {
var obj_as_dict = obj as IDictionary<string,object>;
var fields = ttype.GetFields();
if (fields.Length > 0)
set_fields_from(result, fields, obj_as_dict);
var properties = ttype.GetProperties();
if (properties.Length > 0)
set_properties_from(result, properties, obj_as_dict);
}
}
return result;
}
private void set_fields_from(T _this_, FieldInfo[] fields, IDictionary<string,object> obj) {
foreach (var fld in fields) {
var v = find(obj, fld.Name);
if (v != null) {
var mobj = call_deserialize(fld.FieldType, v);
fld.SetValue(_this_, mobj);
}
}
}
private void set_properties_from(T _this_, PropertyInfo[] properties, IDictionary<string,object> obj) {
foreach (var prop in properties) {
var v = find(obj, prop.Name);
if (v != null) {
var mobj = call_deserialize(prop.PropertyType, v);
prop.SetValue(_this_, mobj, null);
}
}
}
private object find(IDictionary<string,object> obj, string name) {
foreach (var kv in obj)
if (string.Compare(kv.Key, name, true) == 0)
return kv.Value;
return null;
}
private object call_deserialize(Type des_type, object value) {
var gtype = typeof(dynamic_data_serializer<>);
Type desz_type = gtype.MakeGenericType(new[]{ des_type });
object desz = Activator.CreateInstance(desz_type);
var method_type = desz_type.GetMethod("create");
return method_type.Invoke(desz, new[]{ value });
}
}
}
Cảm ơn bạn! Tôi sẽ cố gắng sử dụng nó. Trong trường hợp sử dụng sự phản chiếu, tất cả các thông tin kiểu có thể được lưu trữ. –