Author Topic: Read-Only Property or Method?  (Read 6560 times)

0 Members and 1 Guest are viewing this topic.

SomeCallMeDave

  • Guest
Read-Only Property or Method?
« on: January 12, 2009, 07:56:56 AM »
I am writing, in C#,  some classes for a project that I am playing with and wanted to get some input on read-only properties versus returning values via a method call.

As as simple example

Code: [Select]
     private int mReadOnlyA;
     private int mReadOnlyB;
   
     public int A()
    {
         return mReadOnlyA;
    }

    public int B
    {
        get {return mReadOnlyB;}

     }
     public int Foo(int Input)
    {

        // A and B are calculated here based on Input

     }


Is one way any better or any worse than the other way?  Are there benefits or problems with one or the other that I have yet to see?

Glenn R

  • Guest
Re: Read-Only Property or Method?
« Reply #1 on: January 12, 2009, 11:07:29 AM »
Personally, I would go the readonly property route as .NET pushes the concept of properties. However, I would first consider using the keyword 'readonly' before using properties, if you're using fields.

This has the added bonus that you can initialise in the class constructor ONLY, but gives you added safety as after that it acts like a constant. Also, they can be exposed directly, via a public modifier and you don't even need to use a property. However, if you don't know the values ahead of hand, or are not passed them in the constructor, then go the standard route and declare a private variable and expose it readonly through a property get.

For example:

Code: [Select]
public SomeClass()
{
    public readonly int someInt;  // could also init here in the declaration.

    public SomeClass()
    {
        // init someInt here, but afterwards it's readonly
        someInt = 10;
    }
}

SomeCallMeDave

  • Guest
Re: Read-Only Property or Method?
« Reply #2 on: January 12, 2009, 12:44:19 PM »
Thanks Glenn.   I was leaning toward using read-only properties but wanted to check if there were any benefits/hazards.

Thanks again.

TonyT

  • Guest
Re: Read-Only Property or Method?
« Reply #3 on: January 12, 2009, 07:03:49 PM »
In all but some rare/obscure cases I would say read-only properties
are preferable to methods.

The .NET framework supports data binding to properties, but not to
methods. For example, even though your data is read-only you may
want to let a user see it, which you could if you bind an instance of
your class to a property grid or a row in a data grid. In that case, a
read-only property's value is shown, but not editable.


I am writing, in C#,  some classes for a project that I am playing with and wanted to get some input on read-only properties versus returning values via a method call.

As as simple example

Code: [Select]
     private int mReadOnlyA;
     private int mReadOnlyB;
   
     public int A()
    {
         return mReadOnlyA;
    }

    public int B
    {
        get {return mReadOnlyB;}

     }
     public int Foo(int Input)
    {

        // A and B are calculated here based on Input

     }


Is one way any better or any worse than the other way?  Are there benefits or problems with one or the other that I have yet to see?


SomeCallMeDave

  • Guest
Re: Read-Only Property or Method?
« Reply #4 on: January 12, 2009, 07:27:01 PM »
Thanks Tony.

And thanks for the primer in data binding from another thread.  That is saving a lot of coding.

Ken Alexander

  • Newt
  • Posts: 61
Re: Read-Only Property or Method?
« Reply #5 on: January 12, 2009, 11:02:09 PM »
In addition to what others have said.  Here are a few of my favorite points to consider. 

If I couldn’t or wouldn’t store the value, use a method.  Properties should be settable and retrievable in any order.  If the value you need is based on Properties set in a certain order, use a method.  Another guideline is if calling the member twice in a row produces different results, use a method.   

An example of this would be the age of a person object.  Many wouldn’t blink an eye at making the age a ReadOnly Property.  I feel it should technically be a method that returns the age.  First I wouldn’t store the age in a database; I would store the person’s birth date. An Age property would require a birth date property to be set first. And lastly, if you called the age property twice in a row, you would get different results.
Ken Alexander

Glenn R

  • Guest
Re: Read-Only Property or Method?
« Reply #6 on: January 13, 2009, 05:05:01 AM »
SCMD,

Also, if you're using C# 3.0 or above, I would tend to favour the 'auto-magic' properties. This forces you to internally call the property getter/setter, rather than going straight for the internal field/member variable.

An example:

Code: [Select]
public int someInt { get; private set; }

This allows the outside world to see and get the property value, but only you internally can set it.
The compiler auto-magically generates a backing field for this, so you don't have a member variable you could use to bypass the property and also it forces you to use the property in your internal code.

Cheers,
Glenn.

TonyT

  • Guest
Re: Read-Only Property or Method?
« Reply #7 on: January 13, 2009, 01:59:35 PM »
Hi Ken.

Where are you getting your 'guidelines' from?

Why is the DateTime's 'Now' property, a property, rather than a method?

In addition to what others have said.  Here are a few of my favorite points to consider. 

If I couldn’t or wouldn’t store the value, use a method.  Properties should be settable and retrievable in any order.  If the value you need is based on Properties set in a certain order, use a method.  Another guideline is if calling the member twice in a row produces different results, use a method.   

An example of this would be the age of a person object.  Many wouldn’t blink an eye at making the age a ReadOnly Property.  I feel it should technically be a method that returns the age.  First I wouldn’t store the age in a database; I would store the person’s birth date. An Age property would require a birth date property to be set first. And lastly, if you called the age property twice in a row, you would get different results.

TonyT

  • Guest
Re: Read-Only Property or Method?
« Reply #8 on: January 13, 2009, 03:15:42 PM »
In your example, you calculate the value when you call
a method that sets the dependent data. While that's
ok, I've experienced a number of situations where doing
that can impose unneeded overhead (namely where the
calculated result is dependent on multiple values that
are also exposed as properties, and where setting any one
of them effectively invalidates the cached result).

What I have done in some complicated cases in order to
avoid needless calculation, is use a boolean flag as a
signal that indicates the calculation needs to be done.

That pattern can be useful when the calcuation is very
expensive and dependent on multple values that can be
set independently (namely other read/write properties
whose values are used in the calcuation), as would be
the case in a well-designed interface.

In this example, a class exposes two 'calculated' properties
called 'Weight' and 'Volume'. While the calculations here are
actually not very expensive in reality, let's assume otherwise,
and that they require significant computational overhead.

Code: [Select]

public class Box
{
   private double width;
   private double height;
   private double length;
   
   // I use two leading underscores as a reminder
   // that this member should never be referenced
   // directly, other than from its corresponding
   // property setter/getter:
   
   private double __volume;
   
   // true = volume must be recalcuated:
   
   private bool volume_dirty = true;
   
   private double density;
   private double __weight;
   
   // true = weight must be recalcuated:
   
   private bool weight_dirty = true;
   
   /// Required validation is done in property setters,
   /// so we leverage that from the constructor:

   public Box( double length, double width, double height, double density )
   {
     this.Width = width;
     this.Length = length;
     this.Height = height;
     this.Density = density;
   }
   
   // Common validation
   
   void CheckIsGreaterThanZero( double value )
   {
      if( value < 0.000001 )
         throw new ArgumentException("Value must be reasonably positive and non-zero");
   }

   public double Width
   {
      get
      {
          return this.width;
      }
      set
      {
          CheckIsGreaterThanZero( value );
          this.width = value;
          this.volume_dirty = true; 
      }
   }

   public double Length
   {
      get
      {
          return this.length;
      }
      set
      {
          CheckIsGreaterThanZero( value );
          this.length = value;
          this.volume_dirty = true; 
      }
   }

   public double Height
   {
      get
      {
          return this.height;
      }
      set
      {
          CheckIsGreaterThanZero( value );
          this.height = value;
          this.volume_dirty = true; 
      }
   }

   public double Density
   {
      get
      {
         return this.density;
      }
      set
      {
         CheckIsGreaterThanZero( value );
         this.density = value;
         this.weight_dirty = true;
      }
   }

   // Let's assume the calculations needed to
   // produce these two values are very expensive:
   
   public double Volume
   {
      get
      {
         if( this.volume_dirty )
         {
            this.__volume = length * width * height;
            volume_dirty = false;
         }
         return this.__volume;
      }
   }

   public double Weight
   {
      get
      {
         if( this.weight_dirty )
         {
            this.__weight = this.density * this.Volume; // <--- use the Volume property, not the field
            this.weight_dirty = false;
         }
         return this.__weight;
      }
   }

}


The advantage of the above approach is that it will not
trigger a recalcuation for each assignment to the four
dependent properties (Width, Height, Length and Density),
so if a consumer were to set all of them, there wouldn't
be a recalculation done for each assignment:

Code: [Select]

    public Box box = new Box( 2.0, 4.0, 6.0, 0.25 );
   
    // These assignments will not trigger any internal calcuations:

    box.Width = 3.25;
    box.Height = 12.0;
    box.Length = 5.253;
    box.Density = 0.3125

    // The following line triggers the calcuation of
    // both the volume and weight, in that order:

    console.WriteLine(" The weight of the box is {0}", box.Weight );


The one point that is not obvious, is that even from within
the class, one would never reference the private '__volume'
or '__weight' fields because their values may not be valid at
any given point (and that's why I use two leading underscores
to remind me of it). So even from within the class, the public
property would be used to get the corresponding values, as
the setter for the Weight property gets the calculated volume
in the example.

Taking this approach is useful when using data binding,
because in some cases the value of properties can be
referenced frequently (like from the Paint handler of the
property grid).


I am writing, in C#,  some classes for a project that I am playing with and wanted to get some input on read-only properties versus returning values via a method call.

As as simple example

Code: [Select]
     private int mReadOnlyA;
     private int mReadOnlyB;
   
     public int A()
    {
         return mReadOnlyA;
    }

    public int B
    {
        get {return mReadOnlyB;}

     }
     public int Foo(int Input)
    {

        // A and B are calculated here based on Input

     }


Is one way any better or any worse than the other way?  Are there benefits or problems with one or the other that I have yet to see?

« Last Edit: January 13, 2009, 04:12:52 PM by TonyT »

Ken Alexander

  • Newt
  • Posts: 61
Re: Read-Only Property or Method?
« Reply #9 on: January 13, 2009, 05:40:09 PM »
Hi Tony,

Quote
Where are you getting your 'guidelines' from?

http://msdn.microsoft.com/en-us/library/czefa0ke(VS.71).aspx

Quote
Why is the DateTime's 'Now' property, a property, rather than a method?

Good point.  Seems to be a contradiction to their own guidelines.  Keeping in mind though, they are just guidelines to help enforce consistency.
Ken Alexander

SomeCallMeDave

  • Guest
Re: Read-Only Property or Method?
« Reply #10 on: January 13, 2009, 06:15:04 PM »
Thanks for all the replies.

Good food for thought all.

TonyT

  • Guest
Re: Read-Only Property or Method?
« Reply #11 on: January 13, 2009, 10:29:34 PM »
Hi Ken.

Thanks. In that case, my only question is where do those
guidelines say or imply this:

Quote

    If I couldn’t or wouldn’t store the value, use a method


Which seems to suggest to me, at least, that if the property is
not backed by a private member/field, it shouldn't be a property.

The guidelines you cite do not say that, and your interpretaton
is not exactly correct. I would suggest you reexamine them, and
pay specific attention to the use of the term 'logical data member'.

A logical data member is not necessarily a member whose data is
'stored' in a private member or field.

Another issue with those guidelines, is that they completely ignore
the matter of data binding. If one is using data binding, the question
of whether one should use a property or a method becomes academic
(data binding only works with properties, not with methods).

Hi Tony,

Quote
Where are you getting your 'guidelines' from?

http://msdn.microsoft.com/en-us/library/czefa0ke(VS.71).aspx

Quote
Why is the DateTime's 'Now' property, a property, rather than a method?

Good point.  Seems to be a contradiction to their own guidelines.  Keeping in mind though, they are just guidelines to help enforce consistency.
« Last Edit: January 14, 2009, 01:58:13 AM by TonyT »

Ken Alexander

  • Newt
  • Posts: 61
Re: Read-Only Property or Method?
« Reply #12 on: January 14, 2009, 12:50:46 PM »
Hi Tony,

Sorry, ‘storing the value’ guideline is mine; or I picked it up from some article somewhere.  By storing I was referring to storing in a database or other form.  I almost always use that guideline as my first (not only) determination of Property vs. Method.  Basically the Noun/Verb guideline that came from somewhere.

Quote
A logical data member is not necessarily a member whose data is
'stored' in a private member or field.

I agree.

I don’t agree that they are ignoring data binding.  Here’s why:

“These guidelines are intended to help class library designers understand the trade-offs between different solutions. There might be situations where good library design requires that you violate these design guidelines. Such cases should be rare, and it is important that you provide a solid justification for your decision.”

Plus, they are using data binding in almost every one of their examples related to property usage.  I’m sure data binding would provide a solid justification for possible violations to these guidelines.  Still, I would say only in rare cases could you not follow the guidelines.
Ken Alexander

TonyT

  • Guest
Re: Read-Only Property or Method?
« Reply #13 on: January 14, 2009, 01:22:03 PM »
I don’t agree that they are ignoring data binding.  Here’s why:

“These guidelines are intended to help class library designers understand the trade-offs between different solutions. There might be situations where good library design requires that you violate these design guidelines. Such cases should be rare, and it is important that you provide a solid justification for your decision.”

Plus, they are using data binding in almost every one of their examples related to property usage.  I’m sure data binding would provide a solid justification for possible violations to these guidelines.  Still, I would say only in rare cases could you not follow the guidelines.


Well, I disagree, based entirely on this:

Quote from: Microsoft

   "Such cases should be rare".


Perhaps to someone that's not familiar with data binding or
how to exploit it, it may be 'rare'.

If you ventured into the world of WPF, you would quickly
discover that data binding is ubiquitous, to the point where
just about anything you do with WPF is dependent on it.

While data binding may be rare from your perspective (which
seems to be the case based on your suggested approach to
validation), I can assure you that data binding is nothing but
rare to most experienced. .NET developers.

Hence, we can't say those guidelines can be followed in most
cases, because in almost every case where data binding is used,
the bound data must be exposed through properties in order for
data binding to work.

In fact, many classes I write are written solely  for the purpose
of serving as data sources for data binding. In many cases where
I use a DataGridView to expose data in tabular form, for example,
I bind columns of the grid to properties of the class that I write
specifically for that purpose. The class isn't necessarily the 'true'
source of the data, but rather, it merely serves as an interface
to that data, which makes it possible to use it with data binding.

An example of that, might be where one stores data in AutoCAD
objects (in XData or an XRecord), and they want to allow the user
to edit that data in their UI. A very easy way to do that, is to
write a class that can be handed a DBObject, from which it gets
the data from the XData/XRecord, and exposes it as properties.

The getters and setters of the properties can handle the details
of opening the database object and retrieving or saving the XData
or XRecord data.

Of course, that's just one of hundreds of examples of where
classes that are purposely built only to serve as data binding
sources, can make things much simpler.

And in that context, the question of  'property verses method'
is entirely moot.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8764
  • AKA Daniel
Re: Read-Only Property or Method?
« Reply #14 on: January 14, 2009, 03:14:11 PM »
In some of these cases, wouldn’t it be better to use a struct instead of a class?
Isn’t DateTime a struct and not a class?  :mrgreen: