【发布时间】:2018-10-31 14:55:09
【问题描述】:
我有以下嵌套输入类
//InputClass
public class MessageViewModel
{
public bool IsSelected { get; set; }
public string Subject { get; set; }
public DateTime CreationDate { get; set; }
public List<MessageViewModel> Messages { get; set; }
}
我想创建以下类型的新实例:
//Target Class
public class DestinationClass
{
public string Subject { get; set; }
}
对于每个具有 IsSelected = true 属性的 MessageViewModel 实例 在这种情况下,最好的解决方案是什么?这可以使用 AutoMapper 实现吗?
编辑:
假设我有以下对象:
var vm = new MessageViewModel
{
Messages = new List<MessageViewModel> {
new MessageViewModel {
IsSelected = true,
Messages = new List<MessageViewModel> {
new MessageViewModel { IsSelected = true,
Messages = new List<MessageViewModel> { new MessageViewModel { },
new MessageViewModel { },
new MessageViewModel { } } } } } }
};
我想遍历它并仅提取和映射 IsSelected 等于 true 的 MessageViewModel。
已解决:
使用以下代码:
public static class TraversalHelper
{
public static void TraverseAndExecute<T>(this T composite, Func<T, IEnumerable<T>> selectChildren, Action<T> action)
where T : class
{
action.Invoke(composite);
composite.TraverseAndExecute(selectChildren, action, new List<T> { composite });
}
private static void TraverseAndExecute<T>(this T composite, Func<T, IEnumerable<T>> selectChildren, Action<T> action, IList<T> invokedComponents)
where T : class
{
invokedComponents = invokedComponents ?? new List<T>();
var components = selectChildren(composite) ?? new T[] { };
foreach (var component in components)
{
if (!invokedComponents.Contains(component))
{
action.Invoke(component);
invokedComponents.Add(component);
component.TraverseAndExecute(selectChildren, action, invokedComponents);
}
else
{
}
}
}
}
我设法迭代了我的分层对象:
var vm = new MessageViewModel
{
Messages = new List<MessageViewModel> {
new MessageViewModel {
IsSelected = true,
Messages = new List<MessageViewModel> {
new MessageViewModel {
IsSelected = true,
Messages = new List<MessageViewModel> {
new MessageViewModel { },
new MessageViewModel { },
new MessageViewModel { } } } } } }
};
var results = new List<DestinationClass>();
vm.TraverseAndExecute(_ => _.Messages, _ => {
if(_.IsSelected == true)
{
results.Add(new DestinationClass { Subject = _.Subject });
}
});
【问题讨论】:
-
出于可读性原因,您不应在 C# lambda 中使用下划线。它应该是 Message 的“m”或更好的“message”。您可以使用 Linq 语句对其进行重构,以将其转换为 DestinationClass 的 IEnumerable。此外,您可以将 if 语句简化为 if(_.IsSelected)
标签: c# linq mapping automapper