views:

45

answers:

2
IEnumerable<T> collection;

void MyMethod(T toSearch)
{
  foreach (T t in collection)
    if (t == toSearch) {}
}

The if clause is never true.. is it because the Enumerator creates all the items instances on demand, so everytime a new Reference ?

Edited:

Another question. What happens if I one of those collection elements return in T MyMethod() . Do I have a reference on an existing instance that really resides in memory so that all changes made on it will be reflected in that item.. or the returned element is a new instance.. or I cannot do that .. I don't understand

A: 

The answer is that 'it depends', but enumerators are normally used to go through (enumerate) existing objects.

James L
+1  A: 

Assuming T is a reference type, this will be comparing the exact references - if you pass in a reference which is in the collection, it should match with no problem. It would be extremely odd for the iterator to create clones - although not impossible, of course.

However, it won't use whatever overload of == might be valid for your particular T. For example:

List<string> strings = new List<string> { "hi" };
string hi = "hi";
string otherHi = new string(new char[]{'h', 'i'});

MyMethod(hi); // Will match
MyMethod(otherHi); // Won't match

To use normal equality instead of reference equality, you might want to change your method to say:

if (EqualityComparer<T>.Default.Equals(t, toSearch))
{
    //
}
Jon Skeet
For me neither `t == toSearch` nor `Comparer<T>.Default.Equals(t, toSearch)` compiles ... did you mean `Comparer<T>.Default.Compare`?
tanascius
Most types with an overridden == operator will also implement Object.Equals in the same way, so you can check t.Equals(toSearch)
Dan Bryant
OK and if I return an item from IEnumerable from that Method and I want to give that item another reference ? (a new object).. is it possible ? (I suppose that in that case I'll have to replace foreach with the normal for loop as IEnumerable does not allow to change items.)But is it OK in your opinion to replace assign a new Object to the reference returned from that Method ?
Steve
@tanascius: I meant `EqualityComparer<T>.Default.Equals`. Will fix.
Jon Skeet
@Dan: The problem with using `t.Equals(toSearch)` is that it will box value types (I *believe* - I could be wrong on that front) and it also fails if `t` is null.
Jon Skeet
@Steve: It's not very clear what you mean because your use of terminology is a little ambiguous. It sounds like you're talking about cloning the object. That might or might not be feasible depending on the object in question. What does it mean to clone a `FileStream`, for example?
Jon Skeet
Well I edited the question.. I hope it's clearer now.. You know I just thought that the Enumerator creates the item instances on demand.. so that the cloning is implicit.. what is a nonsense.
Steve
@Jon, you're right, I always forget about null, as most of the time I consider null in a set like this to be an error in the first place. It probably deserves an explicit error check or at least Assert rather than letting it fail implicitly. I also usually ignore boxing; is it significantly slower than the overhead of grabbing an EqualityComparer<T>?
Dan Bryant