1.First I defined an extension method for the IEnumerable.Add() like the code below
public static IEnumerable<T> Add<T, TKey>(this IEnumerable<T> enumerable, T value, Func<T, TKey> orderBy)
{
if (enumerable == null)
return null;
if (enumerable is IList<T>)
{
var list = enumerable as IList<T>;
if (!enumerable.Contains(value))
{
list.Add(value);
enumerable = enumerable.OrderBy(orderBy);
}
}
}
2.Then,I raised the extension method like this to sort the itemlist according to the “Date” property when a new item was added to the list:
itemList.Add(item, o => o.Date);
3.After all,it appears that the “itemList” was not sorted.
4.I followed the extension method and found that “enumerable” was a new instance after “enumerable = enumerable.OrderBy(orderBy)” and it was sorted,but the “list” was not.
5.Then I tried to cast the sorted enumerable to list like “list=enumerable.ToList()”,both of them(“enumerable” and “list”) were sorted.
6.After that ,when the call stack went back to the “itemList.Add(item, o => o.Date);”,the “itemList” was not sorted at all!!!
Anyone can give me some advices?Thanks a looooooooooooooooooooooooooooooooot!!
I believe your problem is that the reference to enumerable is being passed by value rather than by reference. See Jon Skeet’s article about passing parameters by value or reference for more information about what that means. In short, C# passes a copy of the parameter’s reference so assigning a new value to parameter does not change the reference of the object that was passed in. To pass a parameter by reference you specify the
refkeyword, but I don’t think that will work with an extension method. If you’re dead set on making this work I would suggest inserting the items into your List in sorted order, probably requiring that T implement IComparable.Update:
First off, see the Skeet’s article it’s really quite informative and I will probably only be half as clear as he is. Second, when you pass an object as a parameter to a method you are passing a copy of the reference. This means you can still access members of the object but, the same way that a value type is passed by copy, if you modify the reference (ie assign it a new value) you wont modify the original reference. Specifying
refmeans that you are passing a reference to the reference and changing the reference (assigning a value to it) will affect the original object.