티스토리 뷰

웹프로그래밍/.NET

[C#] 정렬

공허공자 2008. 11. 18. 15:17

한글페이지고 뭐고 왜 그리들 어렵게 써놨는지.. C# 초보자는 알수도 없게 해놨던데
외국인이 나같은 초보자도 볼 수 있게 설명해놔서 가지고 왔다.

At the suggestion of my pal Russ Nemhauser, I recently found myself investigating predicates in relation to the Array and List classes in the .NET Framework 2.0. Along the way, I dug a little deeper into sorting arrays, and found a new feature which can save you a bunch of coding.

Imagine that you've got an array of objects, and you want to sort if by one of the properties of the objects. For example, imagine that you've written the following code:

[VB]
Dim di As New DirectoryInfo("C:\")
Dim files() As FileInfo = di.GetFiles("*.*")

[C#]
DirectoryInfo di = new DirectoryInfo(@"C:\");
FileInfo[] files = di.GetFiles("*.*");

Calling the Array.Sort method for this array gets you an InvalidOperationException, because the Array class has no idea on which property you want it to sort. In previous versions of the .NET Framework, you could solve the problem by creating a class that implements System.Collections.IComparer. In this class, the Compare procedure handles the logic that determines how to sort the information, like this code, which sorts the data based on the FullName property:

[VB]
Public Class CompareNames
  Implements IComparer

  Public Function Compare( _
   ByVal x As Object, ByVal y As Object) _
   As Integer _
   Implements System.Collections.IComparer.Compare

    Dim file1 As FileInfo = CType(x, FileInfo)
    Dim file2 As FileInfo = CType(y, FileInfo)

    Return file1.FullName.CompareTo(file2.FullName)
  End Function
End Class

[C#]
public class CompareNames :
  System.Collections.IComparer
{
  public int Compare(object x, object y)
  {
    FileInfo file1 = (FileInfo)x;
    FileInfo file2 = (FileInfo)y;

    return file1.FullName.CompareTo(file2.FullName);
  }
}

To perform the sort, you can write code like this:

[VB]
Dim comparer1 As New CompareNames()
Array.Sort(files, comparer1)

[C#]
CompareNames comparer1 = new CompareNames();
Array.Sort(files, comparer1);

If you then wanted to sort by CreationTime, for example, you would need to create another class, providing a different comparer. What a pain! Not only must you create a new class for each sort order, you must perform the same conversions each time, because the IComparer.Compare method passes Object references, not strongly typed values.

In the .NET Framework 2.0, you have a number of options using generics, but the simplest is to take advantage of the Array.Sort overload that's defined like this:

[VB]
Public Shared Sub Sort(Of T)(array As T(), comparison As Comparison(Of T))

[C#]
Public static void Sort<T>(T[] array, Comparison<T> comparison)

In this overload, you supply a generic array of a particular type, along with a procedure of the appropriate delegate type. The delegate type looks like this:

[VB]
Public Delegate Function Comparison(Of T) (x As T, y As T) As Integer

[C#]
public delegate int Comparison<T> (T x, T y)

All you need to do is create a procedure, like this one, that compares two objects of the same type:

[VB]
Private Function CompareFileNames( _
 ByVal f1 As FileInfo, ByVal f2 As FileInfo) As Integer
  Return f1.FullName.CompareTo(f2.FullName)
End Function

[C#]
public int CompareFileNames(FileInfo f1, FileInfo f2)
{
  return f1.FullName.CompareTo(f2.FullName);
}

It's a lot simpler than creating a new class for each sort, and performing conversions for two objects each time. Given the CompareFileNames procedure, you could perform the sort using code like this:

[VB]
Array.Sort(files, AddressOf CompareFileNames)

[C#]
Array.Sort(files, CompareFileNames);

If you then wanted to sort by CreationTime, you could supply this procedure:

[VB]
Private Function CompareDates( _
 ByVal f1 As FileInfo, ByVal f2 As FileInfo) As Integer
  Return f1.CreationTime.CompareTo(f2.CreationTime)
End Function

[C#]
public int CompareDates(FileInfo fi, FileInfo f2)
{
  return f1.CreationTime.CompareTo(f2.CreationTime);
}

You could sort by CreationDate using this code:

[VB]
Array.Sort(files, AddressOf CompareDates)

[C#]
Array.Sort(files, CompareDates);

I love it. This technique takes the sting out of sorting data structures in multiple ways.

Published Friday, April 21, 2006 8:19 AM by KenG


[출처] http://mcwtech.com/CS/blogs/keng/archive/2006/04/21/154.aspx

댓글