我有两个类 Book 的对象。是否可以合并两个覆盖空值的对象?
图书模型:
public string Author {get; set}
public string Title {get; set}
public string EAN {get; set}
第一本书数据:
Book.Author -> "Adam Wróbel"
Book.Title -> "StackOverflow Book"
Book.EAN-> "777777777"
第二本书数据:
Book.Author -> null
Book.Title -> "StackOverflow Book v2"
Book.EAN-> null
是否可以将这两个对象组合起来得到这样的结果?
Book.Author -> "Adam Wróbel" (data from first book)
Book.Title -> "StackOverflow Book v2" (data from second book)
Book.EAN-> "777777777" (data from first book)
P.S.我知道我可以通过检查语句是否不为空并分配给另一个对象来比较每个字段。但是,这似乎是解决此问题的一种相当有限的方法。
答案 0 :(得分:2)
您可以尝试使用 Automapper 并将其设置为忽略自映射的空值:
var config = new MapperConfiguration(cfg => cfg.CreateMap<Book, Book>()
.ForAllMembers(opts => opts.Condition((src, dest, member) => member != null)));
var mapper = config.CreateMapper();
var target = new Book
{
Author = "1",
Title = "1",
EAN = "1"
};
var source = new Book
{
Title = "2"
};
var book = mapper.Map(source, target);
Console.WriteLine($"{book.Author}-{book.Title}-{book.EAN}"); // prints "1-2-1"
答案 1 :(得分:1)
抱歉,c# 中没有内置任何东西可以做到这一点。您的选择是:
对不起,我不知道有任何图书馆可以做到这一点。也许是 Automapper?
答案 2 :(得分:1)
最好的方法是简单地编写手动映射器。但是,如果您希望在不涉及构造函数的每个简单 POCO 情况下为您执行此操作,以下将使用反射:
public static class Merger
{
public static T CloneAndMerge<T>(T baseObject, T overrideObject) where T : new()
{
var t = typeof(T);
var publicProperties = t.GetProperties();
var output = new T();
foreach (var propInfo in publicProperties)
{
var overrideValue = propInfo.GetValue(overrideObject);
var defaultValue = !propInfo.PropertyType.IsValueType
? null
: Activator.CreateInstance(propInfo.PropertyType);
if (overrideValue == defaultValue)
{
propInfo.SetValue(output, propInfo.GetValue(baseObject));
}
else
{
propInfo.SetValue(output, overrideValue);
}
}
return output;
}
}
请注意,这里没有优化或缓存。我不建议将它用于生产代码,但它是完成您所寻找的内容的一种简单方法。