Je suis tombé sur une question intéressante aujourd'hui : j'ai deux méthodes qui, à première vue, font la même chose. C'est-à-dire retourner un IEnumerable d'objets Foo.
Je les ai définies ci-dessous comme List1 et List2 :
public class Foo
{
public int ID { get; set; }
public bool Enabled { get; set;}
}
public static class Data
{
public static IEnumerable<Foo> List1
{
get
{
return new List<Foo>
{
new Foo {ID = 1, Enabled = true},
new Foo {ID = 2, Enabled = true},
new Foo {ID = 3, Enabled = true}
};
}
}
public static IEnumerable<Foo> List2
{
get
{
yield return new Foo {ID = 1, Enabled = true};
yield return new Foo {ID = 2, Enabled = true};
yield return new Foo {ID = 3, Enabled = true};
}
}
}
Considérons maintenant les tests suivants :
IEnumerable<Foo> listOne = Data.List1;
listOne.Where(item => item.ID.Equals(2)).First().Enabled = false;
Assert.AreEqual(false, listOne.ElementAt(1).Enabled);
Assert.AreEqual(false, listOne.ToList()[1].Enabled);
IEnumerable<Foo> listTwo = Data.List2;
listTwo.Where(item => item.ID.Equals(2)).First().Enabled = false;
Assert.AreEqual(false, listTwo.ElementAt(1).Enabled);
Assert.AreEqual(false, listTwo.ToList()[1].Enabled);
Ces deux méthodes semblent faire la même chose.
Pourquoi les deuxièmes assertions du code de test échouent-elles ?
Pourquoi le deuxième élément "Foo" de listTwo n'est-il pas mis à false alors qu'il se trouve dans listOne ?
NOTE : Je cherche à savoir pourquoi cela est autorisé et quelles sont les différences entre les deux. Je ne cherche pas à savoir comment corriger la seconde assertion, car je sais que si j'ajoute un appel ToList à List2, cela fonctionnera.