.NET - When should I use a property vs. variable + accessor function?

10,963

Solution 1

Properties, internally, are nothing but a pair of methods. They basically evaluate to a get and set accessor method.

You should use properties, unless the property is going to cause some unexpected, potentially long running side effect, or there is some other good reason to use a method.

For details, I suggest reading the Property Usage Guidelines on MSDN. In particular, use a method when:

  • The operation is a conversion, such as Object.ToString.
  • The operation is expensive enough that you want to communicate to the user that they should consider caching the result.
  • Obtaining a property value using the get accessor would have an observable side effect.
  • Calling the member twice in succession produces different results.
  • The order of execution is important. Note that a type's properties should be able to be set and retrieved in any order.
  • The member is static but returns a value that can be changed.
  • The member returns an array.

Otherwise, I'd use a property. Brad Abram's blogged some other details, including good reasons why certain API functions use methods (mostly because they could cause cross-computer communication, which would fall into the "side effect" category).

Solution 2

Properties are actually syntactic sugar for methods called get_MyProperty and set_MyProperty, so there is no performance difference.

Solution 3

Another decision around whether to use properties or functions is when instantiating the parent object. VB has that wonderfully convenient syntax, e.g.

Dim MyStudent as Student With {.Name = "Bobby", .Age = 10}

Only properties are available in the With section.

I maintain an app which has a lot of persisted objects in a database, which a lot of relationships between objects. e.g. a student has a teacher, and the teacher is peristed in the DB.

I typically use a WriteOnly property to set the Teacher, since this is a light operation, but given there is potentially expensive DB access to retrieve the Teacher, I use a function to retrieve. In other words:

Public Writeonly Property Teacher() as Teacher
Public Function GetTeacher() as Teacher

This lets me instantiate a Student in the form With {.Teacher = SomeTeacherObject} but GetTeacher encourages caching of the Teacher object in user code and not just using it as a Property which may or may not result in multiple DB access calls.

If anyone has any comments on this approach I would love to hear them.

Solution 4

Yes, at least in my experience I try to avoid properties and use function and routines in place. Here is my reasons why:

  1. Cannot use properties with delegates. I believe you can in C# but upon
  2. Properties are deceptive, they look like members, but behave like functions. So while you might think you are just looking at a member value you could in fact be initializing the entire system over again because the implementing developer abused lazy instantiation.
  3. Less Code, while it's not a HUGE amount, defining properties in VB requires at least 2 extra lines of code per get or set. The Overhead is double the lines of actual code for a single assignment or return operation. Although small this makes reading code much more difficult, VB is already an obsessively wordy language.

    Private ReadOnly Property Foo As String
        Get
            Return Bar
        End Get
    End Property
    

    vs

    Private Function Foo As String
        Return Bar
    End Function
    
  4. Properties are less flexible you must return what the same value you get. In Other words you can't set the value using a String and get using an Integer or overload setting with a String, or an Integer.

Now to be fair the Reasons I use Properties is to get the = syntax for setting, which this doesn't apply when you have a read only property. Also Properties can be set in the VS editor in the properties dialog.

Solution 5

With N-Tier designs, in my BO, I store property values with an unset value, then set it when accessed the first time.

Private _aValue As integer =-1 
    Private ReadOnly Property aValue As integer
    Get
        If _aValue = -1 Then
            _aValue = DA.General.GetaValue()
        End If
        Return _aValue
    End Get
End Property

In this way, I never worry if I parse properties in the correct order, since I basically lazy load them.

Share:
10,963
Brian Webster
Author by

Brian Webster

[email protected]

Updated on June 07, 2022

Comments

  • Brian Webster
    Brian Webster almost 2 years

    Is there ever a situation where I should do the following in .NET instead of using a property with read/write capability?

    private S as string
    
    public function GetS() as string
         return S
    end function
    
    public sub SetS(byval NewS as string)
        S = NewS
    end function
    

    Do properties simply provide a more efficient way for doing the same thing?

    Will properties be any slower than the above accessor functions in a high performance application?

  • Brian Webster
    Brian Webster over 14 years
    @Reed - Why would anybody ever need a Private Property?
  • Reed Copsey
    Reed Copsey over 14 years
    It makes it easier to add logic that occurs when things are done, plus eases versioning (if later, you decide you need to have extra logic set in there). Simple properties get inlined by the JIT, so there is little reason to avoid using them. Also, private properties can work with data binding.
  • Pavel Minaev
    Pavel Minaev over 14 years
    "The member returns an array" should really be generalized to "member returns a mutable object of reference type that is no longer owned by the object to which that member belonds".
  • Brian Webster
    Brian Webster over 14 years
    @Reed - That helps a bit. It sounds like you would be providing a bit of a wrapper to the internals of an object. Maybe not the smartest thing to do for a simple string or integer member, but may be quite useful for capturing some meta information about an object. Am I on the right path for property's intended usage? Thanks for the links above.
  • Reed Copsey
    Reed Copsey over 14 years
    Yes. It's a good idea to do, if you think you might ever want to provide the "wrapper". For example, if later, you want to implement INotifyPropertyChanged, or have some other change tracking, having the private as a property is useful, since you can change that without changing other code.