C# – Encapsulating a class within another class to hide its exposed properties and details

cclass-design

I have essentially a data model class that represents an XML data structure that we use to model our system. The model class is in a shared project that is used by a number of different solutions in order to generate a common XML data structure for usage by any number of applications.

In one application I am involved in we have provided a wrapper class for one of these XML model classes as we wish to perform a number of operations on the model data. However other parts of my program also needs to access this data for calculations they need to do.

At the moment I have this setup (note this is an example only but represents my code structure)

1)

public class ModelWrapper
{
    private readonly ModelClass _model;

    public int PropertyX 
    { 
      get 
      { 
         return _model.PropertyX;
      }
    }

    public ModelWrapper(ModelClass model)
    {
       _model = model;  
    }

    // and other methods we need that uses the properties we have exposed e.g
    public void PerformOperation()
    {
        if(this.PropertyX > 10)
           // do something
        else
           // do something else
    }
}

This appears ok, but I've run into the problem where I or another programmer has un-intentially used the private _model variable. It seems to me that we could end up with hidden issues in this method in the fact that there are two ways to get to the same data and if we put some logic in the public exposed get property then we could miss that if we directly reference the private variable.

The other alternative I thought of was

2)

public class ModelWrapper
{
    public readonly int PropertyX;

    public ModelWrapper(ModelClass model)
    {
       PropertyX = model.PropertyX;  
       // set other properties here we wish to expose on the ModelClass ...
    }

    // and other methods we need that uses the properties we have exposed e.g
    public void PerformOperation()
    {
        if(this.PropertyX > 10)
           // do something
        else
           // do something else
    }
}

Or another option after reading some posts about this is:

3)

public class ModelWrapper
{
    private readonly int _propertyX;
    public int PropertyX 
    { 
      get { return _propertyX; }
    }

    public ModelWrapper(ModelClass model)
    {
       _propertyX = model.PropertyX;  
    }

    // and other methods we need that uses the properties we have exposed e.g
    public void PerformOperation()
    {
        if(this.PropertyX > 10)
           // do something
        else
           // do something else
    }
}

Why do this? I thought it would be a good idea to hide the model from the our code as we wanted a wrapper class anyway to do the methods so why then expose the model as well? I thought it might be overkill but it does save in other parts of the code going something like ModelWrapper.Model.PropertyX etc

So to the question. Which method if any would be a better solution. Is it overkill or are there better practices out there for this?

EDIT:
I added another option (3) as it there is no need to set the properties I am exposing so I didn't necessarily want to have a private set as it's only being set in the constructor. Hence the readonly private variable that is used in the get part of the exposed property?

I've also found a stack overflow question about this at https://stackoverflow.com/questions/2249980/c-immutability-and-public-readonly-fields but it doesn't necessarilly say which was better/preferred solution with the current c# limitations.

Any ideas on the 3 implementations as to the best practice?

Best Answer

Inside the wrapper, this should not be an issue. Since this.PropertyX is read-only you cannot unintentionally assign it a value and reading it returns the same value as _model.PropertyX.

I do not know any object oriented construction, which hinders a programmer to produce errors.

If you should add logic to the getter in the future, it would be a good idea to give a different name to the property like NormalizedPropertyX or LowerCasePropertyX or the like explicitly stating the intention behind it.