KnowDotNet NetRefactor

Using Overloads and Shared Methods in .NET Classes

Shortcut to Polymorphism

by Les Smith and Brian Davis
Print this Article Discuss in Forums

Using Overloads in .NET classes provides a shortcut method for calling a polymorphic method any number of ways.  The code provided for this article shows how to call one method that can do several things for you without resorting to VB.NET Optional paramaters.  Optional parameters are really neat for a VB programmer, but frowned on by C# programmers.  However, there is a more practical reason for not using optional parameters, because they are not compatible for a DLL written in VB, but which can be called from other languages, such as CSharp.NET.

The code for this article really only does one thing.  It returns the size of file, whose path and file name are passed to it.  However, it has several ways of returning that file size, based on the the parameters that are passed to it, or in some cases, not passed to it.

This article also illustrates the fact that Overloading is not about replication of a lot of code, with only slight variations of the same base code, in each of the overloaded methods.  
Overloading is really about creating one polymorphic method, with multiple overloaded calls, resulting in variations in the return value.  Additionally, it allows me to pass, only the parameters that we want to pass, substituting default parameters as necessary.

This article will also show you that you can mix Shared and non Shared methods in a class, although that is not the major impetus for writing this article.  If all methods of a class are Shared, then, in VB, you should use a module file rather than a shared class.  Again, C# programmers do not have modules at their disposal, although a shared class accomplishes the same thing.  It allows you to reference variables and call methods without having to instantiate an instance of the shared class.  In VB, that's what modules are for.

The VB.NET code for the CFileSize class is shown in Figure 1 below.  It has nine overloaded methods; eight of which are Shared and the ninth, which requires no parameters, is an instance method.  To call the instance method (which by the way, is the first method in the class) you would have to instantiate an instance of the object before calling this method.

If this class did more things than just return the size of the file, I would have created more "instance methods", but again, the real reason for the article is for treating Overloads and to mix in a lot of verbage on Shared vs Instance methods might be a little much for one article.

To call the one instance method, I would have to use the following code.

   Dim o As New CFileSize(fname)
  
Dim s As String = o.GetFileLength()

The real power of Overloading is demonstrated here by the fact that I have real code in only one method, and that method is called by all of the other methods and both the calling and called methods have the same name with different signatures.  By exposing the Enum SizeType, we provide intellisense to the caller for that parameter.

The Shared methods can be called directly by prefacing them with "
CFileSize.", as is illustrated by the following line of code.

   Dim s As String = _
      CFileSize.GetFileLength(ftp & "\" & fname, _
      CFileSize.SizeType.KB, " K", 1)

The return value of the class, for the call shown above, will be something like "21.3 K".  Obviously, since all the methods return String, I am going to use the return value for display.  In the case for which I wrote this class, I am loading the value into a ListView that shows files and there respective sizes.

Figure 1 - VB.NET CFileSize Class.

Option Strict On
Public
Class CFileSize

#
Region "Variables and Properties"
  
Private _FName As String
  Public ReadOnly Property FName() As String
      Get
         Return _FName
      
End Get
   End Property

   Public Enum SizeType
      Bytes
      KB
      MB
      GB
  
End Enum
#End Region

#Region "Business Logic Methods"
  
Public Overloads Function GetFileLength() As String
      Return GetFileLength(_FName, MeSizeType.Bytes, String.Empty, 0)
  
End Function
   Public Overloads Shared Function GetFileLength(ByVal fName As String) As String
      Return GetFileLength(fName, SizeType.Bytes, String.Empty, 0)
  
End Function
   Public Overloads Shared Function GetFileLength( _
      
ByVal fName As String, ByVal FileSizeType As SizeType) _
      
As String
      Return GetFileLength(fName, FileSizeType, String.Empty, 0)
  
End Function
   Public Overloads Shared Function GetFileLength( _
      
ByVal fName As String, ByVal FileSizeType As SizeType, _
      
ByVal Suffix As String) As String
      Return GetFileLength(fName, FileSizeType, Suffix, 0)
  
End Function
   Public Overloads Shared Function GetFileLength( _
      
ByVal fName As String, ByVal Suffix As String, _
      
ByVal Decimals As Short) As String
      Return GetFileLength(fName, SizeType.Bytes, Suffix, Decimals)
  
End Function
   Public Overloads Shared Function GetFileLength( _
      
ByVal fName As String, ByVal FileSizeType As SizeType, _
      
ByVal Decimals As Short) As String
      Return GetFileLength(fName, FileSizeType, String.Empty, Decimals)
  
End Function
   Public Overloads Shared Function GetFileLength( _
      
ByVal fName As String, ByVal Suffix As String) As String
      Return GetFileLength(fName, SizeType.Bytes, Suffix, 0)
  
End Function
   Public Overloads Shared Function GetFileLength( _
      
ByVal fName As String, ByVal Decimals As Short) As String
      Return GetFileLength(fName, SizeType.Bytes, String.Empty, Decimals)
  
End Function
   Public Overloads Shared Function GetFileLength( _
      
ByVal fName As String, ByVal FileSizeType As SizeType, _
      
ByVal Suffix As String, ByVal Decimals As Short) As String
      Dim fi As New IO.FileInfo(fName)
      
Dim s As Single = fi.Length
      
Dim sRet As String = String.Empty
      
Dim sFmt As String = "#,##0"
      
If Decimals > 0 Then
         sFmt &= "." & New String("0"c, Decimals)
      
End If

      Select Case FileSizeType
        
Case SizeType.Bytes
            sRet = s.ToString(sFmt)
        
Case SizeType.KB
            sRet = (s / 1024).ToString(sFmt)
        
Case SizeType.MB
            sRet = (s / (1000 * 1024)).ToString(sFmt)
        
Case SizeType.GB
            sRet = (s / (1000 * 1000 * 1024)).ToString(sFmt)
      
End Select
      Return sRet & Suffix
  
End Function
#End Region


#Region "Constructor"
  
Public Sub New(ByVal filename As String)
      _FName = filename
  
End Sub
#End Region
End
Class

Writing Add-Ins for Visual Studio .NET
Writing Add-ins for Visual Studio .NET
by Les Smith
Apress Publishing