@DavidMills द्वारा स्वीकृत उत्तर काफी अच्छा है, लेकिन मुझे लगता है कि इसमें सुधार किया जा सकता है। एक के लिए, ComparisonComparer<T>
वर्ग को परिभाषित करने की आवश्यकता नहीं है, जब रूपरेखा में पहले से ही एक स्थिर विधि शामिल है Comparer<T>.Create(Comparison<T>)
। इस विधि का उपयोग IComparison
मक्खी पर बनाने के लिए किया जा सकता है ।
इसके अलावा, यह डाले IList<T>
करने के लिए IList
जो संभावित खतरनाक हो गया है। ज्यादातर मामलों में जो मैंने देखा है, List<T>
जो लागू करने के IList
लिए पर्दे के पीछे का उपयोग किया जाता है IList<T>
, लेकिन इसकी गारंटी नहीं है और इससे भंगुर कोड हो सकता है।
अंत में, अधिभार List<T>.Sort()
विधि में 4 हस्ताक्षर हैं और उनमें से केवल 2 को लागू किया गया है।
List<T>.Sort()
List<T>.Sort(Comparison<T>)
List<T>.Sort(IComparer<T>)
List<T>.Sort(Int32, Int32, IComparer<T>)
निम्न वर्ग इंटरफ़ेस के List<T>.Sort()
लिए सभी 4 हस्ताक्षर लागू करता IList<T>
है:
using System;
using System.Collections.Generic;
public static class IListExtensions
{
public static void Sort<T>(this IList<T> list)
{
if (list is List<T>)
{
((List<T>)list).Sort();
}
else
{
List<T> copy = new List<T>(list);
copy.Sort();
Copy(copy, 0, list, 0, list.Count);
}
}
public static void Sort<T>(this IList<T> list, Comparison<T> comparison)
{
if (list is List<T>)
{
((List<T>)list).Sort(comparison);
}
else
{
List<T> copy = new List<T>(list);
copy.Sort(comparison);
Copy(copy, 0, list, 0, list.Count);
}
}
public static void Sort<T>(this IList<T> list, IComparer<T> comparer)
{
if (list is List<T>)
{
((List<T>)list).Sort(comparer);
}
else
{
List<T> copy = new List<T>(list);
copy.Sort(comparer);
Copy(copy, 0, list, 0, list.Count);
}
}
public static void Sort<T>(this IList<T> list, int index, int count,
IComparer<T> comparer)
{
if (list is List<T>)
{
((List<T>)list).Sort(index, count, comparer);
}
else
{
List<T> range = new List<T>(count);
for (int i = 0; i < count; i++)
{
range.Add(list[index + i]);
}
range.Sort(comparer);
Copy(range, 0, list, index, count);
}
}
private static void Copy<T>(IList<T> sourceList, int sourceIndex,
IList<T> destinationList, int destinationIndex, int count)
{
for (int i = 0; i < count; i++)
{
destinationList[destinationIndex + i] = sourceList[sourceIndex + i];
}
}
}
उपयोग:
class Foo
{
public int Bar;
public Foo(int bar) { this.Bar = bar; }
}
void TestSort()
{
IList<int> ints = new List<int>() { 1, 4, 5, 3, 2 };
IList<Foo> foos = new List<Foo>()
{
new Foo(1),
new Foo(4),
new Foo(5),
new Foo(3),
new Foo(2),
};
ints.Sort();
foos.Sort((x, y) => Comparer<int>.Default.Compare(x.Bar, y.Bar));
}
List<T>
जब भी संभव हो छँटाई करने के लिए अंतर्निहित की कार्यक्षमता का लाभ उठाने के लिए यहां विचार है। फिर से, अधिकांश IList<T>
कार्यान्वयन जिन्हें मैंने देखा है वे इसका उपयोग करते हैं। मामले में जब अंतर्निहित संग्रह एक अलग प्रकार है, List<T>
तो इनपुट सूची से तत्वों के साथ एक नया उदाहरण बनाने के लिए कमबैक करें , इसे छँटाई करने के लिए उपयोग करें, फिर परिणाम वापस इनपुट सूची में कॉपी करें। यह तब भी काम करेगा जब इनपुट सूची IList
इंटरफ़ेस को लागू नहीं करती है।