Naming conventions: use member prefixes to avoid collisions?

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Our company is rewriting our product in .NET. The old product is in PowerBuilder, which is heavy on Hungarian notation. We are approaching the time where we have to finalize naming conventions for everything publicly exposed in our API

There are two camps -- the Hungarian camp and the "Readable English" camp. I am in the latter. Like Microsoft's official recommendations for .NET, I have seen the light. Readability is what matters when looking at someone else's code; knowing it's scope, datatype and member type (property, method, event, etc) can be determined both from the type of name (noun, verb, adjective) and by moving the mouse over it in Visual Studio. Hungarian notation is painfully hard to read, and seems to encourage cryptic abbreviations in the non-prefix part of the name as well

The Hungarian camp has lost ground due to the ever-improving Intellisense features in Visual Studio. There is no longer any need to rely on unreliable voluntary prefixing when reliable Intellisense is always there (and no, programmers do not pour over huge paper printouts anymore ...

The final bone of contention is over the risk of member name collisions. The Hungarian camp is balking that unless we use ugly prefixes that no one else will use, we run the risk of .NET or 3rd party base classes adding members (possibly methods, but more likely properties and events) with names we've already used in our subclass. The collission may simply hide the base class's member, or if the return types don't match, it won't even recompile. In either case, if the users of our API want access to the new base class member, we'll have to rename our member (we can get at it inside the subclass using "base.", but outside the subclass that's not possible). All this is assuming that our member and the newly added base class member are indeed conceptually different, so that we can't just retire our member or wrap the base member with ours and let the API users see it as one

How often do member name collisions really occur? If we weren't creating an API for use by customers, this would be no big deal for us to just rename our member -- just do a search & replace on our own code in-house. I still don't see it happening that often that our customers would be burdened if they had to do the same

If anyone has any experience with this, feedback would be appreciated. If we can't come up with actual case studies, then the Hungarian camp will win out of fear mongering (they hold the company's purse strings, too, so they don't have to argue that well ...
 
Namespaces will take care of this problem, the recommended format is companyname.systemname.applicationname...etc. as long as your namespace is unique, collisions will not occur. following the same format for assemblies is also recommended

ht
jayson
 
Using namespaces prevents collisions (allows differentiation, actually) for "type" names -- classes, interfaces, enumerations and delegates. We already use namespaces with the standard convention "Company.System.Application.Feature". (Actually, we're currently only using one namespace, "Company.Application", which is being used out of laziness, but I've already won the battle to break it down further -- we just haven't cleaned up our earliest prototype code yet.)

But what about member names -- methods, properties and events -- and the collisions that occur when a base class created by someone outside our company suddenly gets a member added to it with a name that our subclass already has?

C# has the "new" keyword you can put on members to make the compiler shut up about these kind of collisions, but as far as I know, there's no way to 100% guarantee that this kind of collision won't occur. You can only deal with it when it happens, or try to make it astronomically unlikely by using some obnoxious prefix on on all of our members (like an abbreviation "ffi" for your company "Foofram Industries" on every stinkin' method, property and event -- ffiClear, ffiText, ffiClicked ...) THAT's what the Hungarian camp wants to do, and I say they're insane ...

**********************************************************************
Sent via Fuzzy Software @ http://www.fuzzysoftware.com/
Comprehensive, categorised, searchable collection of links to ASP & ASP.NET resources...
 
Nels P. Olsen said:
But what about member names -- methods, properties and events -- and the
collisions that occur when a base class created by someone outside our
company suddenly gets a member added to it with a name that our subclass
already has?


This is exactly the scenario that C# protects you from by not having
implicit polymorphism. The members in your derived type won't be modified
as overrride on version 1 of the base class. So, if version 2 of the base
class is implemented with a method identical to your class, your code will
not break because the base class method is implicitly hidden. When the base
type implements the identically named method, it won' t accidentally call
your method. When you recompile your code, you'll get the "new" modifier
warning and at that time you can make your intentions explicit by adding the
new modifier.

Joe
 
Nels Olsen said:
The final bone of contention is over the risk of member name
collisions. The Hungarian camp is balking that unless we use ugly
prefixes that no one else will use, we run the risk of .NET or 3rd
party base classes adding members (possibly methods, but more likely
properties and events) with names we've already used in our subclass.
The collission may simply hide the base class's member, or if the
return types don't match, it won't even recompile. In either case,
if the users of our API want access to the new base class member, we'll
have to rename our member (we can get at it inside the subclass using
"base.", but outside the subclass that's not possible). All this is
assuming that our member and the newly added base class member are
indeed conceptually different, so that we can't just retire our member
or wrap the base member with ours and let the API users see it as one.

Even in the hiding case, you'll get a warning unless you use the "new"
modifier, so it's not like you won't find out about it.

In practice, I can't remember this ever happening to me. Prefixes
really don't help, IMO.
 
Nels Olsen said:
Yes, the lack of a "virtual" keyword on a base class member does insure
that a base class reference containing a subclass instance will access the
base class's member, in the situtation where the subclass has a member with
the same signature, but that's not our problem (or, more correctly, the mad
prefix-happy camp's worry -- what follows below I do not even consider a
problem, but I still have to neutralize the issue ...)

Lucky you. :)
Say you have a base class from a 3rd party toolkit called CircusPerformer.
Your company is making a product with a public API, and it has it's own
"base" class wrapper, OurCircusPerformerBase, and several subclasses
(HighWireWalker, Clown, etc -- details not necessary). You notice that in
releaase 1 of the 3rd party toolkit, there's no method called Juggle. You
wonder why they didn't put it in their base class, since many of the
different performers juggle during their act. So, you add Juggle to
OurCircusPerformerBase. You release our product and its public API.
A year later you get release 2 of the 3rd party toolkit. They finally got
around to adding Juggle to their CircusPerformer base class. Potential
problem:
If your Juggle method returns a different datatype than the 3rd party's
Juggle method, will your code even recompile? I don't know. Are you forced
to change the name, or change the return type (withdrawing that signature
from your API)? This is probably more likely with properties than
methods -- e.g. the toolkit has a type called Thingy, your API subclasses it
as OurThingy, you subclass a toolkit base class and add a property
DefaultThingy as type OurThingy, then the toolkit adds a property to the
base class called DefaultThingy as type Thingy.

Sure, it will compile. The return type doesn't cause any problems in
hiding, but will cause a compiler error if you want to override a new
virtual base class method. Properties that don't override will hide
regardless of their type, but different return types will cause a compiler
error when trying to override a virtual base class property.
Even if there is no "hard" collision (i.e. the code still compiles, with
base class references and subclass references getting the correct member at
runtime), there still may be "confusion" to developers. If
OurCircusPerformerBase's idea of Juggle is somewhat different, new API users
familiar with the raw 3rd party CircusPerformer.Juggle behavior may be
confused when they invoke Juggle on a OurCircusPerformerBase reference,
expecting the 3rd party toolkit behavior. To this concern I say RTFM, but
our market is oddly toward "non-technical" people wanting to make "quick and
easy" customizations to our product through our API (or wizards that will
generate the code for you). The mad prefix-happy camp wants to put an
abbreviation of our company name on EVERY public method, property and event
in our API's classes, so that even "soft" collisions will not occur
(assuming the toolkit manufacturer doesn't take up the same naming scheme
....)

Where I see the prefix convention breaking down is when you really do want
to override members of the 3rd party base class, which will make your API
inconsistent. If you are using composition, I don't believe there will be
any technical problem.

Joe
 
Back
Top