views:

127

answers:

7

I'm wondering whether it's insane to (almost) always use custom data types in C# rather than relying on built in types such as System.Int32 and System.String.

For instance, to represent a persons First name, the idea is to use a data type called PersonFirstName rather than System.String (of course, the PersonFirstName data type would have to contain a System.String). Another example is to have a PersonID class which represents the database identifier for the person, rather than to have a System.Int32.

There would be some benefits here:

  • Today, if a function takes an int as parameter, it's easy to pass in an ID of a Company object rather than the ID of an Person object, because both are of types int. If the function took a CompanyID, I would get a compilation error if I tried to pass in a PersonID.

  • If I want to change the database column data type from int to uniqueidentifier for a Person, I would only have to make the change in the PersonID class. Today, I would have to make changes in all places which takes an Int and is supposed to represent a company.

  • It may be easier to implement validation in the right places. " " may never be a correct first name, which PersonFirstName can take care of.

Yes, I would have to write more constructors. I could implement implicit overloading in these to make them easy to work with though.

Is this madness?

+6  A: 

Yes, utter madness - to sum up your idea, and to Paraphrase Blackadder

It's mad! It's mad. It's madder than Mad Jack McMad, the winner of this year's Mr Madman competition

iAn
Great feedback! :)
Martin
+1 for using BlackAdder...
Philip Wallace
+1  A: 

Yes, madness AND OVERKILL...

astander
+2  A: 

No, you're not getting any real benefit of that. For some things it makes sense, perhaps an Email class or maybe, maybe an ID class. However, having a "PersonID" or "ClientID" class seems to go far. You could have a "typedef" or alias or whatever but I would not go too far with this in most circumstances. You can go overboard very quickly and end up with a lot of work for no benefit.

BobbyShaftoe
What do you mean I wouldn't get any real benefit? A typedef or an alias would not solve benefit 1 and 3 which I listed. Being able to distinguish a PersonID from a CompanyID may be a real benefit, right? At the one end, we have using string's for everything. At the other far end we have using custom data types for everything. The optimal way is somewhere in the middle, right?
Martin
System.Net.Mail.MailAddress for emails ;)
iAn
@Martin, your complaint is almost interesting but I did address those issues by saying there may be some circumstances, such as in the case of an Email class or whatever. There is no question that what you propose would "solve 1 and 3" but to provide benefit you need to solve a real problem that can actually impact you. The fact that you are asking suggests you think it may not be beneficial enough. Typedefs are used for this sort of thing but they don't solve 1 and 3 no; they aren't meant to solve the "I accidentally passed in the wrong type" problem.
BobbyShaftoe
+2  A: 

Yes... It is ! You will loose more than you gain.

Dani
Have you actually done this yourself or are you making a guess?
Martin
If you build your software correctly, there are other ways to make sure the right values no going to the wrong fields.I usually generate classes for all Table and column names from the DB (so errors will be detected in compile time) and I use meaningfull names to all variables and properties - even if temporary, I have unit tests that checks everything all the time, and usually if I have some knowledge about the field I use it in the Setter - to validate it. In cases that it is very very important - I use enums - which is similar to what you do.
Dani
+1  A: 

It sounds like a maintenance nightmare to me. what would the CompanyID constructor take? An integer? Sooner or later - you are going to have to use native types whether you like it or not.

Philip Wallace
Of course, at some point the software would have to care about native types. But in my case, this would be taken care of by the OR-mapper.
Martin
+4  A: 

I don't think that's madness. I think using business logic objects with strongly typed objects is a very good thing

Chad
+1. To do it for "almost all" cases would be madness. But it makes good sense for the examples quoted. It's one of the standard refactorings, ExtractClass http://www.refactoring.com/catalog/extractClass.html
MarkJ
@MarkJ: It *doesn't* make good sense for the examples quoted. If the OP wants the benefit of OO and strong-typing then the answer is to pass around `Person` objects rather than the individual `int` and `string` members. Creating lots of useless, single-field `PersonFirstName`, `PersonID` etc objects *isn't* refactoring and *isn't* a sensible solution.
LukeH
+1  A: 

So what I see here at first glance is a question within a question. Basically:

How do I mitigate complexity and change in my code base?

I would say that you need to look at the problem you are trying to solve and first see what the best solution is going to be. If you are dealing with something that is potentially going to be pervasive throughout your code base then you might want to see if you are violating SOLID design principles. Chances are that if you have one type that is being used in A LOT of different places your design is way too coupled, and you have a poor separation of concerns.

On the other hand, if you know that this type is going to be used in a lot of places, and it also happens to be very volatile (changes is certain), then the approach you mention above is probably the right way to go.

Ask yourself "What problem am I trying to solve?" and then choose a solution based on that answer. Don't start with the answer.

Josh
I have no problem which I'm trying to solve. I just wanted feedback on my question.
Martin
If you are looking for a direct answer then I can't give you one. As you can see from the other answers given there is room for disagreement. One can then extrapolate that the answer simply depends on the problem at hand. I am simply trying to highlight the circumstances under which solution is better suited than another. To blindly state that one solution is superior than the other misses the point, and leads to dogmatism. All design decisions need to be understood for their pros and cons in order to make an informed decision about when, or when not to use them.
Josh