John Murray · Feb 13, 2018

Do you always use unique names for class members?

Documentation here lists the kinds of members a class definition may contain. In summary:

  • Parameters
  • Methods
  • Properties
  • Class queries
  • XData blocks
  • Projections
  • (and some that are relevant only for persistent classes):
    • Storage definitions
    • Indices
    • Foreign keys
    • SQL triggers

Later in the same document, a section headed "Class Member Names" contains this warning:

So I'm interested to hear how other DC members handle this.

  1. Do you comply (or at least attempt to comply) with this?
  2. If so, do you use any tools or naming conventions to assist you?
  3. Have you ever encountered "unexpected results" that were caused by a failure to comply?
5 0 7 279
Log in or sign up to continue

There is a short answer to this and a long explanation. The short answer is that the warning is accurate and you might experience problems if you use the same name for two class members. When defining classes myself, I keep method names and property names distinct, mostly by using nouns and verbs. For indices, I prefix the name with a letter indicating the index type.

The reason why you should avoid non-unique names is simple. Most member types inherit methods from what I refer to as the member super tree. The member super tree has an abstract top node with two subnodes, the member super class and the declared type class. The member super class for properties is often called the "property class" and the declared type class is the class the author defines as the type. Methods inherited from the member super tree are implemented in the resolved member runtime as a composite name formed from the member name and the method name. For a property named 'Foo', you might see methods in the class runtime named 'FooSet' and 'FooGet'.

If two members share a name it is possible that a composite method name will conflict between the two member types. We try to avoid this when implementing our member super classes and our type classes but it is still possible to encounter runtime method name conflicts.

Thanks, I found this technical explanation useful.

Has ISC ever considered implementing switchable compile-time enforcement of this uniqueness?

At one time - in the pre-2.0 days of Caché Objects - we did discuss this but decided to settle on the implementation we currently have. The landscape is much more complex these days and there is a greater chance of a composite method name collision or parameter name collision. Not too long ago, I had to redesign the index constraint projection (primary key, unique) and referential constraint projection (foreign key) because we had name collisions.

Since the time when there was a Projection to C# I have adopted unique names.
It was an incredible pain if names were not unique.


I agree in relation to Method and Property members. But it seems less clear to me for other sorts of member. For instance,  an Index on a Property. Or a Foreign Key declaration for one.

My natural inclination would be to use NameIDX for an index; which goes back to me saying that naming is so unrestricted and easy, earlier.  A lot of my early programming experience came from school, where the Department saddled us with the use of a custom implementation of C++ which forced heavy abstraction with strict definition rules, everything was black-box components.  To keep sane you had to name carefully, I guess I internalized that more than I thought.  Sorry to distract from the discussion.

Honestly, John, the idea of NOT using unique names is foreign to me, I do not understand why someone would be tempted to do so.  To me it would seem illogical to create members with the same name because I would question whether that member's function is needed and makes sense in the design.  Plus, naming is not restrictive so it is too easy to make names unique.  Class,Name, Class.GetName, Class.Names, Class.Name.Assign; I would only confuse myself calling all those just Class.Name and wonder if they are all needed; if Class.GetName will always give me the same as Class.Name, why have it?  Maybe I am missing the point, but that's my take.