views:

426

answers:

11

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... this strikes me as a little indecent :)

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

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

         s1.ExamineStudentsMembers(s2);
      }
   }

   public class Student {

      private String _studentsPrivateMember;

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

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

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?

+8  A: 

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.
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
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
A: 

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
A: 

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
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
+5  A: 

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
+6  A: 

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
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
yeah very good hiding place 'in yer face' ;)
Wouter
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
Yeah, you could - but that defeats the purpose of programming through an interface.
Darren Oster
+1  A: 
  • 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
i like the second point, you can look, but dont touch those private members.
Aran Mulholland
+2  A: 

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
+1  A: 

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.

Isaac Cambron
+2  A: 

i like the second point, you can look, but dont touch those private members. – Aran Mulholland 9 hours ago

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.

Julz
A: 

more information in this one

Fredou
A: 

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.

TheEruditeTroglodyte
That's not what he was asking. The question was why are private members accessible to other instances of the same class.
Repo Man