Trong ứng dụng của tôi, tôi phải sử dụng ExpandoObject để tạo/xóa các thuộc tính trong suốt thời gian chạy; Tuy nhiên, tôi phải ánh xạ ExpandoObject trả về của một hàm cho đối tượng/lớp tương ứng. Vì vậy, tôi đã đưa ra một Mapper nhỏ mà thực hiện công việc nhưng với 3 vấn đề:Ánh xạ đệ quy ExpandoObject
- Nó không đệ quy đệ quy các đối tượng bên trong của ExpandoObject như được cho là.
- Khi tôi cố gắng ánh xạ int vào một Nullable chỉ đơn giản là nó sẽ ném một loại không phù hợp vì tôi không thể tìm thấy một cách để phát hiện và đúc nó đúng cách.
- Các trường không thể được ánh xạ
public string Property;
.
Code:
I- Thực hiện:
public static class Mapper<T> where T : class
{
#region Properties
private static readonly Dictionary<string, PropertyInfo> PropertyMap;
#endregion
#region Ctor
static Mapper() { PropertyMap = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).ToDictionary(p => p.Name.ToLower(), p => p); }
#endregion
#region Methods
public static void Map(ExpandoObject source, T destination)
{
if (source == null)
throw new ArgumentNullException("source");
if (destination == null)
throw new ArgumentNullException("destination");
foreach (var kv in source)
{
PropertyInfo p;
if (PropertyMap.TryGetValue(kv.Key.ToLower(), out p))
{
Type propType = p.PropertyType;
if (kv.Value == null)
{
if (!propType.IsByRef && propType.Name != "Nullable`1")
{
throw new ArgumentException("not nullable");
}
}
else if (kv.Value.GetType() != propType)
{
throw new ArgumentException("type mismatch");
}
p.SetValue(destination, kv.Value, null);
}
}
}
#endregion
}
II: Cách sử dụng:
public static void Main()
{
Class c = new Class();
dynamic o = new ExpandoObject();
o.Name = "Carl";
o.Level = 7;
o.Inner = new InnerClass
{
Name = "Inner Carl",
Level = 10
};
Mapper<Class>.Map(o, c);
Console.Read();
}
internal class Class
{
public string Name { get; set; }
public int? Level { get; set; }
public InnerClass Inner { get; set; }
public string Property;
}
internal class InnerClass
{
public string Name { get; set; }
public int? Level { get; set; }
}
Bất kỳ câu trả lời ... –