13

We have a Student class in our business model. something struck me as strange, if we are manipulating one student from another student, the students private members are visible, why is this?

   class Program {
      static void Main(string[] args) {

         Student s1 = new Student();
         Student s2 = new Student();

         s1.SeePrivatePropertiesAndFields(s2);
      }
   }

   public class Student {

      private String _studentsPrivateField;

      public Student() {
         _studentsPrivateField = DateTime.Now.Ticks.ToString();
      }

      public void SeePrivatePropertiesAndFields(Student anotherStudent) {
         //this seems like these should be private, even from the same class as it is a different instantiation
         Console.WriteLine(anotherStudent._studentsPrivateField);
      }
   }

Can i have some thoughts on the design considerations/implications of this. It seems that you can't hide information from your siblings. Is there a way to mark a field or member as hidden from other instances of the same class?

Aran Mulholland
  • 23,555
  • 29
  • 141
  • 228
  • I wouldn't say it's very wrong. From a business model's perspective maybe it is, but it is how you implement it that determines the conformance to the business model. – o.k.w Jan 19 '10 at 00:45
  • 1
    +1, never knew this type of access was allowed. – Doctor Blue Jan 19 '10 at 00:45
  • 6
    If you can't access internal variables of other instances, how are you going to write comparison methods? – Anon. Jan 19 '10 at 00:47
  • 1
    @Anon: You could write comparison methods if the private members were exposed through some properties. I just discovered this privacy strangeness. It seems like they should add another privacy level, like instance-private or something. – user420667 Jul 01 '11 at 16:15
  • more information in this [one](http://stackoverflow.com/questions/1357496/can-you-explain-this-thing-about-encapsulation) – Fredou Jan 19 '10 at 12:02

11 Answers11

9

There's an easy way to ensure this:

Don't mess around with private members of other instances of the same class.

Seriously - you're the one writing the Student code.

Anon.
  • 58,739
  • 8
  • 81
  • 86
  • yeah thats fair enough, especially as its not really an issue because derived classes can't see the private members. In other words a Student's child can't see their parents private members – Aran Mulholland Jan 19 '10 at 01:00
  • Yes this paradigm works, but when you code to allow this sort of access you're just begging for it to be abused outside of any black-box intent. +1 for the reality check. – Joel Etherton Jan 19 '10 at 01:51
8

The easiest way to ensure this is to program to an interface, such as:

class Program
{
    static void Main(string[] args)
    {
        IStudent s1 = new Student();
        IStudent s2 = new Student();

        s1.ExamineStudentsMembers(s1);
    }
}

public interface IStudent
{
    void ExamineStudentsMembers(IStudent anotherStudent);
}

public class Student : IStudent
{
    private string _studentsPrivateMember;

    public Student()
    {
        _studentsPrivateMember = DateTime.Now.Ticks.ToString();
    }

    public void ExamineStudentsMembers(IStudent anotherStudent)
    {
        Console.WriteLine(anotherStudent._studentsPrivateMember);
    }
}

This will no longer compile due to ExamineStudentsMembers trying to access a private field.

Darren Oster
  • 9,146
  • 10
  • 48
  • 66
  • very nice isolation, you've certainly kept those private members out of sight of the other students, and inyerface is a good place to hide student members. – Aran Mulholland Jan 19 '10 at 01:07
  • 2
    This doesn't keep the private members out of sight at all.. It is just not accessing them. I could `just not access them` without adding an interface... Or with the interface in place I could still add another method that takes a Student parameter ( `private ExamineStudentDirectly(Student anotherStudent) { }` ) that does access other instance's private members. – Charles Bretana Jan 19 '10 at 14:26
  • Yeah, you could - but that defeats the purpose of programming through an interface. – Darren Oster Jan 20 '10 at 04:30
6

If you are writing the class, you have complete control over it, so if you don't want one object to be able to modify another, don't write in that functionality.

Classes will often use private variables in other instances to implement efficient comparison and copy functions.

Paul Rayner
  • 392
  • 1
  • 4
4
  • Private just means that the member (field/method/etc.) can be accessed only from the within the code of the parent type. From CSharpOnline
  • Private members of multiple instances are visible and can be invoked. This comes in handy when you are implementing a "copy constructor" or a "clone" method on your type, where the argument is an instance of the same type. If the designers would have made private fields inaccessible, then you may have to create a bunch of getter methods just for clone/copy to get at them. IMHO, I like it better the way it is. Within the same type, Reading another object's state isn't that bad as writing to it though (which could be a DONT-code-convention for you/your team.)
Gishu
  • 134,492
  • 47
  • 225
  • 308
2

Accessing a sibling's private data may seem wrong when phrased like:

public void ExamineStudentsMembers(Student anotherStudent) {
    //this seems very wrong
    Console.WriteLine(anotherStudent._studentsPrivateMember);
}

However, it doesn't seem so odd for methods which require this sort of functionality. What methods require accessing a sibling's private data? Comparison methods (in particular equals) and objects in a data structure (say a tree or linked list).

Comparison methods often compare private data directly rather than just the public data.

For a class of nodes that make up a linked list, graph or tree, being able to access a sibling's private data is exactly what is needed. Code in the know (part of the class) can tinker around with the data structure, but code outside of the data structure cannot touch the internals.

It is interesting to note that these two cases are less common in day-to-day programming than when this language feature were first developed. Back in 1990s and early 2000s, in C++ it would have been much more common to build custom data structures and comparison methods. Perhaps it is a good time to reconsider private members.

Jonathan Wright
  • 14,880
  • 4
  • 24
  • 19
2

i like the second point, you can look, but dont touch those private members.

it's funny you should say that, i knew a teacher once and he said he often had a problem deciding what classes it was ok to look at the members and which ones he could actually have a play with.

Aran Mulholland
  • 23,555
  • 29
  • 141
  • 228
Julz
  • 101
  • 1
  • 3
  • 13
1

An object is just a piece of data; the class contains the functionality. A member method is just a nice trick the compiler plays; it's really more like a static method with an implied argument (sort of like extension methods). With that in mind, protecting objects from each other doesn't make any sense; you can only protect classes from each other. So it's natural that it works that way.

0

No, this is necessary, the method code is not specific to the instance, it is only specific to the type of the object. (virtual methods) or the declared type of the variable (for non-virtual methods). The non-static fields, on the other hand, are instance specific... That's where you have instance-level isolation.

The only difference between a static method and a non-static method is that the static method is not allowed to access other instance based (non-static) methods or fields. Any method that CAN be made static without modification will not be affected in any way by making it static, except to force compiler to throw errors anywhere it was called using instance-based syntax.

Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
0

If you intend to examine a given student's information then I would change the method to be static:

  public static void ExamineStudentsMembers(Student student)
  {
     Console.WriteLine(student._studentsPrivateMember);
  }

You would then use Student.ExamineStudentsMembers(s1). Using s1.ExamineStudentsMembers(s2) would be invalid.

If this isn't the intended purpose I would rewrite the method as:

  public void ExamineStudentsMembers()
  {
     Console.WriteLine(_studentsPrivateMember);
  }

The above would then be used by writing s1.ExamineStudentsMembers()

Ahmad Mageed
  • 94,561
  • 19
  • 163
  • 174
  • the same design issue applies however. Ive noticed this while using statics. a static method can access the private members of the class – Aran Mulholland Jan 19 '10 at 01:01
0

Private members are to hide implementation details from clients. The clients should only see the interface (public methods / fields / properties).

The purpose is not to protect the programmer from himself.

This is also NOT a security feature because you can always access private fields via reflection.

It's really to separate interface & implementation (black box design), and clients programming against a contract (all public fields).

For example if you have a public get property, it could access some private field directly, or it could calculate the value from some other fields. The purpose is, the client only knows the contract (the public property) and the implementation can be changed without affecting the client

-1

Object scope does not ever imply security - ever! It is role of the OS to provide runtime security. It is a bug to design a system that relies on language specific object scope to limit runtime object instance data access. If this were not the case, then all non OO languages are, by definition, not secure.