我想做的事情看起来非常简单-我想在 ICollection< T> 中找到一个满足给定谓词的元素,然后将其替换为另一个。在C ++中,我会这样写:
for(auto& element:collection){ if(predicate(elem)){ element = newElement; } }通过引用获取元素并重新分配。但是这样做
foreach(集合中的ref var元素) 中的p>无法编译,而且我不确定如果编译后它是否还能执行我想要的操作。如何访问集合中的物理引用以对其进行修改?
我的方法签名是否有帮助:
public static void ReplaceReference< T>( ICollection< T集合, T newReference, Func< T,bool>谓词)编辑:
由于不清楚,我不能只需将 ICollection< T> 更改为其他名称即可。我得到一个 ICollection -这就是我所知道的,我无法更改。无论我多么希望自己成为 IList 或 IEasilyReplacable 的人,我都不能对此造成影响。 / p>
解决方案所以我把头撞在墙上,想出了一个非常简单的解决特定替换问题的方法,那就是找到,删除并添加。
var existing = collection.FirstOrDefault(predicate); if(existing!= null) { collection.Remove(existing); collection.Add(newReference); }但是,我认为这是解决我的 foreach 问题,因此已将此问题作为后续发布:通过引用在foreach中从集合中获取的抓取元素
编辑:
对于丹尼尔·怀特(Daniel A. White)的评论:
我只打算处理第一个,但是可以很容易地更改为替换-全部:
var现有=集合。 foreach(现有的var元素) { collection.Remove(element); } for(int i = 0; i将使用索引器替换值
for(int i = 0; i< list .Count; ++ i) { if(predicate(list [i])) { list [i] = newReference; //如果替换为一个变体,则在此处中断。 } }现在在main方法中,我们检查是否收集了是IList,因此是有序的,并将其传递给有序版本:
if(集合为IList< T>列表) b $ b { ReplaceReference(list,newReference,predicate); 的回报; }================ ================================================== ========
边注:当然也有dumbo方法:
var newCollection = new List< T>(); foreach(集合中的var元素) { newList.Add(predicate(element)?newReference:element); } collection.Clear(); foreach(newCollection中的newElement) { collection.Add(newElement); }但是效率很低。
The thing I wanna do would appear really simple - I want to find an element in an ICollection<T> that satisfies a given predicate and replace it with another. In C++ I would write this like:
for(auto &element : collection) { if(predicate(elem)) { element = newElement; } }Grab the element by reference and reassign it. However doing
foreach(ref var element in collection)in C# fails to compile, and I'm unsure if it'd even do what I want if it did compile. How do I access the physical reference within a collection to modify it?
My method signature if it helps:
public static void ReplaceReference<T>( ICollection<T> collection, T newReference, Func<T, bool> predicate)EDIT:
Since it appears unclear, I cannot just take the ICollection<T> and change it to something else. I'm getting an ICollection - that's all I know and I can't change that. No matter how much I'd love this to be an IList, or IEasilyReplacable I can't influence that.
解决方案So I bashed my head against the wall and came up with a really simple solution for the particular replace problem, which is to find, remove and then add.
var existing = collection.FirstOrDefault(predicate); if (existing != null) { collection.Remove(existing); collection.Add(newReference); }However, I see it as rather a workaround to my foreach issue, and have thus posted this question as a follow-up: Grab element from a Collection by reference in a foreach
EDIT:
For Daniel A. White's comment:
Handling only the first one was what I intended to do, but it can be easily changed to replace-all:
var existing = collection.Where(predicate); foreach(var element in existing) { collection.Remove(element); } for(int i = 0; i < existing.Count); ++i) { collection.Add(newReference); }As for ordering - ICollection is not necessarily ordered. So the way for fixing that would be creating a new method with a less general signature
static void ReplaceReference<T>( IList<T> list, T newReference, Func<T, bool> predicate)that would use the indexer to replace the values
for(int i = 0; i < list.Count; ++i) { if(predicate(list[i])) { list[i] = newReference; // break here if replace-one variant. } }And now in the main method we check if our collection is an IList, therefore ordered, and pass it to the ordered version:
if(collection is IList<T> list) { ReplaceReference(list, newReference, predicate); return; }===========================================================================
Sidenote: of course there is also the dumbo approach:
var newCollection = new List<T>(); foreach(var element in collection) { newList.Add(predicate(element) ? newReference : element); } collection.Clear(); foreach(var newElement in newCollection) { collection.Add(newElement); }but it's highly inefficient.
更多推荐
如何替换集合中的元素
发布评论