Lets say you are writing a card game and you need to be able to sort a player's cards into numerical and suit order.
You have written a PlayingCard class, and you have to find a way of sorting by these 2 criteria.
The .Net (OOP) way is to make that class implement the IComparable interface. This simply adds a function that decides if one class instance is 'greater then, less than or equal to' another instance of the same class. Write your sorting rules into this function body and that is. You don't have to worry about moving items into the right places in the array, or type conversion problems, or anything like that. The Array.Sort() function calls your implementation of the IComparable interface and communicates directly with it without your intervention.
Here is a nice example I just cooked up.
(The important parts are highlighted in red).
Copy this code into a console app and run it. It also demonstrates the overriding of the Tostring() function.Code:Module Module1 Sub Main() Dim Deck() As PlayingCard = New PlayingCard(99) {} Dim i As Integer Dim r As Random = New Random For i = 0 To 99 'randomize the array Deck(i) = New PlayingCard(r.Next(PlayingCard.CARDVALUE.Ace, PlayingCard.CARDVALUE.King + 1), r.Next(PlayingCard.CARDSUIT.Spades, PlayingCard.CARDSUIT.Diamonds + 1)) Next i PlayingCard.AcesHigh = True Array.Sort(Deck) For i = 0 To 99 Console.WriteLine(Deck(i)) Next i Console.ReadLine() End Sub End Module Public Class PlayingCard Implements IComparable 'IMPORTANT #Region "Game Specific" #Region "Enums" Public Enum CARDVALUE Ace = 1 Two = 2 Three = 3 Four = 4 Five = 5 Six = 6 Seven = 7 Eight = 8 Nine = 9 Ten = 10 Jack = 11 Queen = 12 King = 13 HighAce = 14 End Enum Public Enum CARDSUIT Spades = 0 Hearts = 1 Clubs = 2 Diamonds = 3 End Enum #End Region #Region "Shared" Public Shared AcesHigh As Boolean = False #End Region #Region "Member Data" Private _Value As CARDVALUE = CARDVALUE.Ace Private _Suit As CARDSUIT = CARDSUIT.Spades #End Region Public Property Value() As CARDVALUE Get Return _Value End Get Set(ByVal RHS As CARDVALUE) If RHS = CARDVALUE.HighAce Then Throw New ArgumentException("Cannot set Value to HighAce directly, set Value to Ace and set AcesHigh variable to True") _Value = RHS End Set End Property Public Property Suit() As CARDSUIT Get Return _Suit End Get Set(ByVal RHS As CARDSUIT) _Suit = RHS End Set End Property Public ReadOnly Property IsHighAce() As Boolean Get Return (_Value = CARDVALUE.Ace) And AcesHigh End Get End Property Public ReadOnly Property IsRoyalty() As Boolean Get Return (_Value >= CARDVALUE.Jack) And (_Value <= CARDVALUE.King) End Get End Property Public Overrides Function ToString() As String Dim s As String Select Case _Value Case CARDVALUE.Ace s = "Ace of " Case CARDVALUE.Two s = "Two of " Case CARDVALUE.Three s = "Three of " Case CARDVALUE.Four s = "Four of " Case CARDVALUE.Five s = "Five of " Case CARDVALUE.Six s = "Six of " Case CARDVALUE.Seven s = "Seven of " Case CARDVALUE.Eight s = "Eight of " Case CARDVALUE.Nine s = "Nine of " Case CARDVALUE.Ten s = "Ten of " Case CARDVALUE.Jack s = "Jack of " Case CARDVALUE.Queen s = "Queen of " Case CARDVALUE.King s = "King of " End Select Select Case _Suit Case CARDSUIT.Spades s &= "Spades" Case CARDSUIT.Hearts s &= "Hearts" Case CARDSUIT.Clubs s &= "Clubs" Case CARDSUIT.Diamonds s &= "Diamonds" End Select Return s End Function #End Region Public Sub New(ByVal itsValue As CARDVALUE, ByVal itsSuit As CARDSUIT) Value = itsValue Suit = itsSuit End Sub Public Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo 'where the Sorting logic is run 'Basically says: "if ME greater than the obj card then return 1, if equal return 0 and if less than, return -1" If Not TypeOf obj Is PlayingCard Then Throw New ArgumentException 'make sure obj is a card before continuing Dim temp As PlayingCard = CType(obj, PlayingCard) Dim vObj As CARDVALUE = temp.Value Dim vMe As CARDVALUE = _Value Dim s As CARDSUIT = temp.Suit If _Suit < s Then 'suits take precedence Return -1 ElseIf _Suit > s Then Return 1 Else If AcesHigh Then 'some games require aces to have a value of 14 rather than 1, hence "Aces High" If vObj = CARDVALUE.Ace Then vObj = CARDVALUE.HighAce If vMe = CARDVALUE.Ace Then vMe = CARDVALUE.HighAce End If 'if suite are the same, check the card numbers... If vMe < vObj Then Return -1 ElseIf vMe > vObj Then Return 1 Else Return 0 'cards are identical (if you are using more than 1 deck deck of cards in a program) End If End If End Function End Class
The output looks like this...


Reply With Quote

