How to create two methods with the same signature - Pierre Henri Kuaté's blog

How to create two methods with the same signature

Using the example of my previous post, we are going to extend the Folder entity.
- For a root folder, we must specify the drive in which this folder is.
- For a sub-folder, we must specify the folder in which this sub-folder is.
For the sake of this example, we will emulate typed DataSets (that is, not use OOP :D): This drive/folder is specified using its identifier (an integer, for example).

Therefore, we would like to create these two constructors:
public Folder(int driveId, string folderName) {...}
public Folder(int folderId, string subFolderName) {...}
However, this is not possible... (Do I need to explain why? :D)

So what is the solution?

I first thought about adding a "dummy" parameter, to have different signatures :D
After a quick "blushing", I reviewed other options:
- Changing the order of the parameters (More "blushing")
- Using a boolean (Bad! See previous post)
- Creating a constructor taking both identifiers (as nullable integers):
Folder rootFolder = new Folder(driveId, null, folderName);
Folder subFolder = new Folder(null, folderId, subFolderName);
I really don't like that.

I ended up with one constructor allowing to do this:
Folder rootFolder = new Folder(driveId, folderName, FolderType.Root);
Folder subFolder = new Folder(folderId, subFolderName, FolderType.Sub);

I am still a little bit annoyed with this solution because the first parameter has different meanings depending of the value of the third parameter... But I can't find a better one; can you?
Published 11 November 2006 05:23 PM by Pierre Henri

Comments

# Pierre Henri Kuat?? : Never use boolean in method signatures said on 11 November, 2006 05:31 PM

PingBack from http://dotnet.org.za/kuate/archive/2006/11/11/Never-use-boolean-in-method-signatures.aspx

# roaan said on 12 November, 2006 07:32 PM

Just another idea.

Use inheritance

"pseudo" code to follow

public class Folder

{

 protected Folder (int id, string name, FolderType theType) {}

}

public class RootFolder

{

 public RootFolder (int id, string name) : base( id, name, FolderType.Root) {}

}

public class SubFolder

{

 public class SubFolder (int id, string name) : base (id, name, FolderType.Sub) {}

}

So what does this gain you...

Not much, but since it seems there is going to be difference in behaviour for the 2 types (maybe not a lot now, but possibly more in the future)

it might be better to have them as seperate classes.

# roaan said on 12 November, 2006 08:32 PM

Oops, forgot to say that RootFolder and SubFolder derives off of Folder

# Pierre Henri said on 12 November, 2006 10:34 PM

@Roaan

This may be a good solution if RootFolder and SubFolder are really "differents" (behavior and functionalities).

On the other, it brings a lot of issues like: How do you move a folder from the root into another one?

In your case, you will have to instanciate a new one with the values of the folder to move, then update all its subfolders...

It is much like the "roles issue": When you have a class User, do you add the property IsAdministrator or do you derive a class Administrator?

Anyway, this is a purely academic discussion; in the real-world, the "good" solution depends of your specifications.

# Ernst Kuschke said on 13 November, 2006 09:22 AM

I don't see why you'd want to differentiate between root- and subfolders this way :-) What is the difference between the two? The fact that one has a parent, while the other doesn't. Whynot let your object model reflect this?

public class Folder

{

   private Folder parentFolder;

   public Folder ParentFolder

   {

       get {...}

       set {...}

   }

   //lots of ctors & methods

}

If the parentFOld is null, it's a root folder, if not, it's a subfolder ;o)

# Pierre Henri said on 13 November, 2006 10:13 AM

As I said "we will emulate typed DataSets (that is, not use OOP :D)". So the solution must use identifiers.

Anyway, we can still have:

public int ParentFolder

{

      get {...}

      set {...}

}

if(ParentFolder == 0) it's a root folder, if not, it's a subfolder; :)

The whole problem is the constructor(s). I could create just one taking the folderName (or even no one), but I wanted to avoid uncontrolled changes by the client code...

# Bob Archer said on 13 November, 2006 11:47 PM
A couple other options: 1. Use a naming convention. If folderName starts with \ then the folder is a root. 2. Make a SetAsRoot public method. Require the user set it to true for root folders. Either way your user has to specify this... I don't see what having it in the constructors buys. Your client could code: Folder f = (new Folder(id, name)).SetAsRoot(.t.) 3. I know you don't want to use OOP, but you could make Folder a genric class. BOb
# Ernst Kuschke said on 14 November, 2006 02:12 PM

"not use OOP..."

But.... why??? :P

# Pierre Henri said on 14 November, 2006 04:16 PM

@Bob,

Thanks for the suggestions; however, it looks like there is no really nice solution to this little problem.

@Ernst,

I was writing my own "object/relational mapping" :D

Using OOP would have required that I implement cascading when loading a folder from the database: when I load a sub-folder, I would have to load its parentFolder/driver, etc.

Too complex for the project I was working on :)

# Sergey Koshcheyev said on 18 December, 2006 10:57 PM
In case you are still looking to solve this problem, a common solution is to use factory methods instead of constructors: Folder root = Folder.CreateRootFolder(...); Folder subfolder = Folder.CreateSubFolder(...);
# Pierre Henri said on 19 December, 2006 11:34 AM

Yes, that's a solution :)

Tough, I don't like factories a lot :D

# what are the two methods in naming a set said on 10 June, 2008 01:26 PM

Pingback from  what are the two methods in naming a set