Page 1 of 1

Extending Classes with more Functionality Giving arrays new abilities. Rate Topic: -----

#1 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2257
  • View blog
  • Posts: 9,450
  • Joined: 29-May 08

Posted 17 February 2009 - 04:08 PM

Extending Classes

What extending classes allows you to do is to extend the capabilities of a class without having to rewrite to it.

How to implement them. Add a new module to your project (In this tutorial call it Extensions)

Example 1 Give any collection type the functionality of stating if all it contents are the same.
Add this code inside the Extensions Module
 <System.Runtime.CompilerServices.Extension()> _
Public Function ContentsAllTheSame(ByRef ThisCollection As ICollection) As Boolean
  Dim TheSame As Boolean = True
  Dim i As Integer = 0
  Dim prev As Object = ThisCollection(0)
  i += 1
  While i < ThisCollection.count
   If ThisCollection(i) <> prev Then
	TheSame = False
   End If
   i += 1
  End While
  Return TheSame
 End Function



Note the <System.Runtime.CompilerServices.Extension()> _ that the magic line of code that make what are to do possible.

Which can be written in less code using LINQ
 <System.Runtime.CompilerServices.Extension()> _
  Public Function ContentsAllTheSame(ByRef ThisCollection As IEnumerable) As Boolean
  Return (From ce In ThisCollection Select ce Distinct).Count = 1
 End Function



Usage example
Module Module1

 Sub Main()
Dim a()={1,1,2}
Dim b()={1,1,1}
Dim c as new List(Of integer)
c.add(2)
c.add(2)
c.add(2)
Console.WriteLine("Is contents of A all the same? {0}",a.ContentsAllTheSame}
Console.WriteLine("Is contents of B all the same? {0}",b.ContentsAllTheSame}
Console.WriteLine("Is contents of C all the same? {0}",c.ContentsAllTheSame}
Console.ReadLine
End Sub
End Module



But I hear you say "Why not just use Functions?"

The next example will show my reasoning of why you should use them.

How to get the Standard Deviation (Population) of the 2nd column of a 2 dimensional array?
First add to the Extensions module the code to perform the Standard Deviation
<System.Runtime.CompilerServices.Extension()> _
  Public Function PopulationStandardDeviation(ByVal nl As IEnumerable(Of Double)) As Double
  Dim Mean As Double = nl.Average
  Dim l As IEnumerable(Of Double) = (From n As Double In nl Select CDbl((n - Mean) ^ 2))
  Dim S As Double = Math.Sqrt(l.Sum / (l.Count - 1))
  Return S
 End Function
[code]
[i]I used LINQ to work out the Standard Deviation but you can use other method.[/l]

Next add the code to extract a column of an array
How to get a column of an Array
[code]
 <System.Runtime.CompilerServices.Extension()> _
 Public Function GiveMeArrayColumn(ByVal TheArray As System.Array, ByVal ColumnNumber As Integer) As System.Array
  If IsArray(TheArray) = False Then Return Nothing
  If ColumnNumber > TheArray.GetUpperBound(0) Or ColumnNumber < 0 Then Return Nothing
  Return (From ae In TheArray).Where(Function(value, ItsIndex) (ItsIndex Mod (TheArray.GetUpperBound(1) + 1)) = ColumnNumber).ToArray
 End Function


How to use.
Module Module1
Public Sub Main()
Dim a()={{1,5,9,13},{2,6,10,14},{3,7,11,15},{4,9,12,16}}
Dim StdDev as Double=a.GiveMeArrayColumn(1).PopulationStandardDeviation
Console.WriteLine("The Standard Deviation of the 2nd column is {0} ",StdDev)
End Sub
End Module



I think the code above is a lot easier to understand, than the functionally equivalent code below.

Module Module1
Public Sub Main()
Dim a()={{1,5,9,13},{2,6,10,14},{3,7,11,15},{4,9,12,16}}
Dim StdDev as Double= PopulationStandardDeviation(GiveMeArrayRow(a,1))
Console.WriteLine("The Standard Deviation of 2 row is {0} ",StdDev
End Sub
End Module



Extra: Get a row of an Array as an Array
 <System.Runtime.CompilerServices.Extension()> _
 Public Function GiveMeArrayRow(ByVal TheArray As System.Array, ByVal RowNumber As Integer) As System.Array
  If IsArray(TheArray) = False Then Return Nothing
  If RowNumber >TheArray.GetUpperBound(0) Or RowNumber < 0 Then Return Nothing
  Dim l As Integer = (TheArray.GetUpperBound(1) + 1) * RowNumber
  Dim u As Integer = l + (TheArray.GetUpperBound(1)  + 1)
  Return (From ae In TheArray).Where(Function(value As Object, ItsIndex As Integer) ((ItsIndex >= l) And (ItsIndex < u))).ToArray
 End Function



Why not build yourself a collection of extensions contains the abilities you require? I have.

Go on become an Extension using D.I.C. Head.

Is This A Good Question/Topic? 0
  • +

Page 1 of 1