Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A very common C# pattern that breaks a very fundamental OOP principle

Here is a very simple question, which I'm still very uneasy about:

Why is it widely accepted now for a class to return a reference to its private member through an accessor method? Doesn't this totally break the encapsulation principle? If this is OK, then why not just make the member public!?

public class EncapsulationViolator
{
  private object abuseMe;

  public object AbuseMe 
  {
    get { return abuseMe; }
  }
}

Edit The case I was considering is this

EncapsulationViolator ev = new EncapsulationViolator();

object o = ev.AbuseMe;

o.SetValue(newValue);

Now ev's state has change through transitivity because its member abuseMe's state has changed.

In the context of DDD, this is not OK if the object is an Aggregate Root. I quote

Allow external objects to hold references to the root only. Transient references to internal members can be passed out for use within a single operation only. Because the root controls access, it cannot be blindsided by changes to the internals.

[Domain-Driven Design, Eric Evans]

... setters schmetters ...

like image 248
samus Avatar asked Jul 18 '12 14:07

samus


People also ask

What is a word for very common?

monotonous. passable. prosaic. run-of-the-mill. stale.

What does common mean in slang?

7-9. Common, vulgar, ordinary refer, often with derogatory connotations of cheapness or inferiority, to what is usual or most often experienced. Common applies to what is accustomed, usually experienced, or inferior, to the opposite of what is exclusive or aristocratic: The park is used by the common people.

What is an example of a common?

The definition of common is something that belongs to or is shared by two or more people or the community at large. An example of common is the knowledge of drivers to stop at a red light. Having no special designation, status, or rank. A common sailor.

What is a common used?

Common Use means any Goods, Services or Works procured by the Council which are required for use by more than one Department of the Council or by Maintained Schools.


1 Answers

You're conflating the C++ term "reference" with the fact that C# passes objects by value (of their reference).

In this case the caller of the getter AbuseMe cannot swap out the private field abuseMe. Thus, there is no violation of encapsulation.

EncapsulationViolator x = new EncapsulationViolator();
object y = x.AbuseMe;
y = 17; // I have not changed x.AbuseMe

Debug.Assert(y != x.AbuseMe); // Passes!

Furthermore, property getters and setters allow for proper encapsulation of private fields and is functionally identical to implementing these as methods (in fact they are implemented as methods by the compiler).

One case in which returning a private variable could break encapsulation is when you return a reference to an array:

class X
{
    private int[] amazing = new int[10];

    public int[] Amazing { get { return this.amazing; } }
}

X a = new X();
int[] x = a.Amazing;
int[] y = a.Amazing;

x[2] = 9;
Debug.Assert(x[2] != y[2]); // Fails!
like image 125
user7116 Avatar answered Sep 25 '22 03:09

user7116