我有以下功能可以工作并循环3个可能的级别。 有没有办法像下面的函数一样,但不必执行多个foreach语句? 基本上,响应列表可以包含多个GroupResponseTypes 每个都可以包含多个ElementResponseBaseTypes 它本身可以是各种类型 我有兴趣在ElementResponseType中找到一个值 并且每个ElementResponseBaseType本身可以是GroupResponseType,它包含多个类型。
因此,我正在寻找一种简单的方法来扫描整个结构中的特定Element.Reference 并返回相关值
非常感谢任何帮助
public static string GetValueFromFormField(List<ResponseBaseType> responses, string fieldref)
{
string fieldvalue = String.Empty;
foreach (GroupResponseType groups in responses)
{
foreach (ElementResponseBaseType firstelements in groups.Responses)
{
if (firstelements.GetType() == typeof(ElementResponseType))
{
if (firstelements.Element.Reference == fieldref)
{
ElementResponseType firstelement = new ElementResponseType();
firstelement = (ElementResponseType)firstelements;
fieldvalue = firstelement.Value;
}
}
else if (firstelements.GetType() == typeof(GroupResponseType))
{
GroupResponseType secondgroup = new GroupResponseType();
secondgroup = (GroupResponseType)firstelements;
foreach (ElementResponseBaseType secondelements in secondgroup.Responses)
{
if (secondelements.GetType() == typeof(ElementResponseType))
{
if (secondelements.Element.Reference == fieldref)
{
ElementResponseType secondelement = new ElementResponseType();
secondelement = (ElementResponseType)secondelements;
fieldvalue = secondelement.Value;
}
}
else if (secondelements.GetType() == typeof(GroupResponseType))
{
GroupResponseType thirdgroup = new GroupResponseType();
thirdgroup = (GroupResponseType)secondelements;
foreach (ElementResponseBaseType thirdelements in thirdgroup.Responses)
{
if (thirdelements.GetType() == typeof(ElementResponseType))
{
if (thirdelements.Element.Reference == fieldref)
{
ElementResponseType thirdelement = new ElementResponseType();
thirdelement = (ElementResponseType)thirdelements;
fieldvalue = thirdelement.Value;
}
}
}
}
}
}
}
}
return fieldvalue;
}
答案 0 :(得分:1)
您需要确定重复使用代码的哪些部分并将其分解为新方法。如果你一遍又一遍地这样做,最终你会得到这样的东西:
public static string GetValueFromResponses(IEnumerable<ElementResponseBaseType> responses, string fieldref)
{
foreach (ElementResponseBaseType response in responses)
{
ElementResponseType element = response as ElementResponseType;
if (element != null)
{
string foundValue = CheckElement(element, fieldref);
if (foundValue != null)
{
return foundValue;
}
}
else
{
GroupResponseType group = response as GroupResponseType;
if (group != null)
{
string foundValue = GetValueFromResponses(group.Responses, fieldref);
if (foundValue != null)
{
return foundValue;
}
}
}
}
return string.Empty;
}
private static string CheckElement(ElementResponseType element, string fieldref)
{
if (element.Element.Reference == fieldref)
{
return element.Value;
}
return null;
}
这是一个使用Linq的版本(它包含原始方法中的所有功能):
public static string GetValueFromResponses(IEnumerable<ElementResponseBaseType> responses, string fieldref)
{
var foundInElements = responses.OfType<ElementResponseType>()
.Select(e => CheckElement(e, fieldref));
var foundInGroups = responses.OfType<GroupResponseType>()
.Select(g => GetValueFromResponses(g.Responses,
fieldref));
return foundInElements.Concat(foundInGroups)
.FirstOrDefault(s => s != null) ?? string.Empty;
}
private static string CheckElement(ElementResponseType element, string fieldref)
{
if (element.Element.Reference == fieldref)
{
return element.Value;
}
return null;
}
答案 1 :(得分:0)
您应该为您的基类型(在本例中为ResponseBaseType
)提供一个返回其所有死代叶节点的成员。然后,您可以为每种类型单独实现该成员的行为。组类型可以返回其所有子节点中的所有叶子(递归地),并且单个项目可以返回自身。
然后,您可以获取基类型的任何实例并获取所有叶子,或者在本例中为第一个叶子。请注意,由于您只是尝试获取第一个结果,而不是所有结果,因此您可以从使组成员的实现使用延迟执行中受益,这样您就不需要费心计算所有值只是为了得到第一个。
起初看起来很复杂,实际实现的代码很少。
public abstract class ResponseBaseType
{
public abstract IEnumerable<ElementResponseType> Leaves { get; }
}
public class GroupResponseType : ResponseBaseType
{
public IEnumerable<ResponseBaseType> Children { get; private set; }
public override IEnumerable<ElementResponseType> Leaves
{
get
{
return Children.SelectMany(child => child.Leaves);
}
}
}
public class ElementResponseType : ResponseBaseType
{
public override IEnumerable<ElementResponseType> Leaves
{
get
{
yield return this;
}
}
}
这使您可以获取响应列表,将其映射到所有叶子的序列,然后从中获取第一个/最后一个叶子。
responses.SelectMany(response => response.Leaves).Last();