我想在迭代循环之外改变一个IEEumerable XElement集合(更改属性,子等),它是一个单独的方法。我发现这对引用或赋值是不可能的,因为IEnumerable只返回/产生一个值。
此方法将子节点添加到XElement:
protected static void setErrorOnItem(ref XElement item, DiagErrorCode errorCode, DiagStatus errorLevel) {
XElement errorNode = new XElement("Error");
errorNode.SetAttributeValue("errorCode", errorCode.ToString());
errorNode.SetAttributeValue("errorLevel", errorLevel.ToString());
item.Element("Errors").Add(errorNode);
}
除非它位于XElement集合循环的上下文中,否则它将正常工作,该集合由IEnumerable迭代器处理。
可以在循环内设置节点上的属性。但是,如果无法完成引用和赋值,我怎么能把这个逻辑放在它自己的方法中呢?
public IEnumerable<XElement> GetRevisedVariationOverTime(IEnumerable<XElement> items) {
foreach(XElement item in items) {
if(sampleSize < RequiredSampleSize) {
// Works fine...
item.Attribute("Status").Value = DiagStatus.WARNING.ToString();
// Can't assign
item = getItemReplacement(item);
// Can't reference
setErrorOnItem(ref item);
}
}
...
return items;
}
答案 0 :(得分:2)
修改集合中的项目应该是安全的,只要您不直接或间接地修改集合本身。您的代码显然打算更改集合中的项目(item = getItemReplacement(item);
),因此您当然无法做到这一点。
如果您想用新元素替换当前元素,可以执行以下操作:
public IEnumerable<XElement> GetRevisedVariationOverTime(IEnumerable<XElement> items)
{
foreach(XElement item in items.ToList()) // note the ToList() call here
{
if(sampleSize < RequiredSampleSize)
{
item.Attribute("Status").Value = DiagStatus.WARNING.ToString();
var newItem = getItemReplacement(item);
setErrorOnItem(ref newItem, ...);
// do the replacement
item.Parent.ReplaceWith(newItem);
}
}
}
答案 1 :(得分:2)
首先,您的GetRevisedVariationOverTime
方法不会像其签名那样返回IEnumerable<XElement>
,并且您对setErrorOnItem
的使用与其声明不符......所以我'我必须猜测你想要做什么。 (我也看不出item
参数需要ref
。)
我怀疑你真的想要这样的东西:
public IEnumerable<XElement> GetRevisedVariationOverTime(IEnumerable<XElement> items) {
foreach(XElement item in items) {
if(sampleSize < RequiredSampleSize) {
// Works fine...
item.Attribute("Status").Value = DiagStatus.WARNING.ToString();
// yield a replacement item
yield return getItemReplacement(item);
// you probably want to do this before you yield the item
setErrorOnItem(item);
}
}
}
然后使用 GetRevisedVariationOverTime
来修改这样的序列:
foreach (var item in GetRevisedVariationOverTime(items))
{
// the items returned are now those yielded by `getItemReplacement`
}
答案 2 :(得分:2)
如果您的方法采用IEnumerable<XElement>
并返回相同的值,则可以在迭代时修改序列。例如:
public IEnumerable<XElement> GetRevisedVariationOverTime(IEnumerable<XElement> items)
{
foreach ( var item in items ) {
if ( sampleSize < RequiredSampleSize) {
yield return GetItemReplacement( item );
}
else {
// return item as-is
yield return item;
}
}
}
XElement GetItemReplacement( XElement item )
{
// modify item in-place and return it,
// or create a whole new XElement and return that instead...
}