Decades of confusion plague value types . . .

Will they never learn?

Conrad Weisert
December 3, 2013
© 2013 Information Disciplines, Inc.


Background

Fifteen years ago we noted a puzzling habit among some promoters of object-oriented programming: trying to distinguish somehow between an object and the value of that object. We particularly cited OOP classes that provided a getValue() accessor function, undermining the basic notion of encapculation and data hiding.

Ten years later we encountered this example in a book about C#, from five authors:1

  class  Money 
    {
     private decimal amount;
    
     public decimal Amount
     {
       get
       {
        return amount;
       }
       set
       {
        amount = value;
       }
     }
     .
     .

If you're unacquainted with C# that's roughly the equivalent of this C++ code:

  class  Money      {
     private: decimal amount;

   public:              //  Accessors
     decimal getAmount() {return amount;}
     void    setAmount(decimal value) {amount = value;}
     .
     .

What's wrong with that?

It provides unrestricted access to the internal representation of a Money object. What would a user-programmer do with that? Probably write pretty-much the same Fortran-like code he2 would have written before he ever heard of OOP.

The authors offered an unconvincing apology:

"This example is here just to illustrate syntactical features of C#.   C# already has a predefined type to represent currency amounts, decimal, so in real life you wouldn't write a class to duplicate this functionality, unless you wanted to add various other methods to it."

Wrong, wrong, wrong on several counts!

  1. The C# decimal type is in no way suitable for representing amounts of money. A decimal quantity is an abstract number, specifying no units (dollars, etc.). Units integrity is one of the valuable by-products of numeric objects. A program is allowed to multiply two decimal numbers (square dollars?), as well as all sorts of other arithmetic operations that yield nonsense for amounts of money.

  2. There's no need for the write accessor ("setter"). The user program can simply assign Money objects.

  3. There's no need for the read accessor ("getter") either. The object itself has a value which can enter into arithmetic operations and be displayed as a string. What else would a program do with it?

    In fact, such accessors undermine object integrity.

A C++ Money class is available on this web site. A C# equivalent is under development and will be posted soon.

The property trap and other C# anomalies

Unlike C++ and Java, C# supports the notion of a property, a way of facilitating (read and write) public access to member data. Some misguided programmers were already in the habit of providing accessor functions for nearly every member data item, and now C# is making it easier. After two decades of object-oriented technology we still encounter programmers who believe that providing read and write accessor for every private member data item is some sort of standard canonical form. They provide the accessors unthinkingly, and appreciate the labor saving offered by C# properties.

Making it easy to do something that shouldn't be done at all is a negative feature. Another C# peculiarity is requiring the new operator not only for allocating reference types from heap storage, but also for initializing value objects in place (stack storage). What is the result returned by the latter new? This is very confusing to beginners.


1—If you need to know who the authors were, send me a request at cweisert@acm.org. We wouldn't want to embarrass them in public if they've reconsidered since 2008.
2—We use the male pronoun here because the offenders we've encountered so far have all been male programmers. We'll update the footnote if further examples demand gender equality.

Return to Technical articles
IDI Home page

Last modified May 25, 2015