Tech Off Thread

18 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

Feature Request: property encapsulated variables

Back to Forum: Tech Off
  • User profile image
    Jupiter Moon

    Hi,

    I have a feature request for C#: Property encapsulated variables.

    Everybody knows that its best practice to encapsulate fields into public properties rather than expose the field itself.  Now I often find it is a good idea to do this with private fields as well and encapsulate them with private properties.

    For example, I may have a private property that represents my database connection and I may wish to initialize it at the last minute with:
            private Command MyCommand
            {
                get
                {
                    if (myCommand == null)
                    {
                        myCommand = new Command("storedprocedure");
                    }
                    return myCommand;
                }
            }

    This is a fairly common pattern and sometimes I use more complex ones which require private encapsulation (the GOF State pattern for example).

    Now the problem is, if a developer (or me) were to pick up my code and then accidently do myCommand.Execute() instead of MyCommand.Execute() we could hit a potential bomb out in run time (as the compiler will allow this).

    My proposal to fixing this issue?  Allow the property to encapsulate its own variables.  Like so:

            private Command MyCommand
            {
                Command myCommand;
                get
                {
                    if (myCommand == null)
                    {
                        myCommand = new Command("storedprocedure");
                    }
                    return myCommand;
                }
            }
    This way only the property can access the variable, further encapsulating and protecting.  In fact this design works for public/protected/internal properties as well.  This is because the overal objective is to protect the variable from it's class (moving ownership of the variable out of class scope and into property scope only).

    In my opinion this is very much inline with OOP principles and improves the OOPness of C#.

    Of course you could argue I create another class called MyCommand which encapsulates the variable and use that but that's just even more work (plus not always realistic).

    Would really appreciate some feedback and would love to see it in the next C#!

  • User profile image
    TommyCarlier

    I love what you suggest. I've struggled with similar stuff myself. Instead of limiting the feature to properties, I think it should be generalized and also be available for methods.

  • User profile image
    mYsZa

    Nice feature Smiley Until it's implemeted in C#, you can always use the singleton pattern for the Command class. Instead of this:

    Jupiter Moon wrote:
    
            private Command MyCommand
            {
                Command myCommand;
                get
                {
                    if (myCommand == null)
                    {
                        myCommand = new Command("storedprocedure");
                    }
                    return myCommand;
                }
            }


    You'll have:

    Command.Instance("IDENTIFIER").Execute();

    You will encapsulate the command behaviour in the class, which is maybe more OOP than using properties? I don't know, I would do so Smiley

  • User profile image
    JohnAskew

    I think making a contained class instead of a property is the best design choice to protect that private data member from the owning class.

    Properties are not meant to contain data, they are interfaces.
    Classes contain data, with relevant overhead...
    My .02

  • User profile image
    littleguru

    JohnAskew wrote:
    I think making a contained class instead of a property is the best design choice to protect that private data member from the owning class.

    Properties are not meant to contain data, they are interfaces.
    Classes contain data, with relevant overhead...
    My .02


    I think you are right. If somebody wants to encapsulate a variable, why not create a private struct or class? Putting the variable in the property introduces mixing of interface with data management.

  • User profile image
    Yggdrasil

    JohnAskew wrote:
    I think making a contained class instead of a property is the best design choice to protect that private data member from the owning class.


    I agree with you here.
    With proper refactoring support from your IDE of choice, turning a field into an encapsulated property is a matter of seconds. The next step is a refactoring that can turn a property into a nested type (maybe even with an implicit casting operation from the original type).

  • User profile image
    Jupiter Moon

    JohnAskew wrote:
    I think making a contained class instead of a property is the best design choice to protect that private data member from the owning class.

    Properties are not meant to contain data, they are interfaces.
    Classes contain data, with relevant overhead...
    My .02


    I disagree with this statement.  Properties are not interfaces (an interface is something completely different).  To understand why I disagree with you we need to go back to the purpose and definition of a property in C#: according to MS their purpose is to encapsulate private fields or to quote:

    A properties is "a private data member accompanied by accessor functions and is accessed syntactically as a field of a class".

    C# is one of the few languages to use properties (e.g. Java really uses methods - infact in C# under the hood properties are just special methods).

    If the purpose of a property is to provide access to private fields why shouldn't the property own that field?

    I'm against the argument of creating a class as, though sometimes the correct thing to do (if you want to Type your variable for example) this can sometimes become a little silly and you end up with a large number of classes which just have one public property which wrap the real class you wish to access.   Now I believe in decoupling but there's a limit! (Yes you could merge them into one class but that is messy and goes against loads of best practice rules).

    Also sometimes its not practicle.  Suppose I create a wrapper for a File object called MyFileObject which has some special methods particular to my application.  In it want to lazy load the FileInfo by using a private property.  So should I move this private property out into a separate class? Then I'd have three classes: MyFileObject, MyFileInfoWrapper, FileInfo.  Isn't that possibly a bit silly especially seeing all I want to do is protect my private field.

    Overall a seperate class risks making your code harder to maintain and the first thing you'll have to do when refactoring is 'remove the middle man' Tongue Out!

    So basically, if the purpose of a property is to encapsulate a field then surely it should be possible to do it in a way where it can FULLY encapsulate it rather than just partially (which would be more OOP)?

  • User profile image
    JohnAskew

    Of course properties are not an interface as in IUnknown.
    Properties are interfaces for those private data members they provide accessors for.

    Did Anders forget to give properties the ability to hold data? I think not. I think he designed it the way it should be, and not the way you propose because he's thought about it longer and has more experience than we do. I understand the design as is. Introducing having private data inside a property is too close to being a contained class imho, and those cases should be contained classes.

    I'm used to properties from using Delphi, fwiw.

  • User profile image
    AndyC

    Jupiter Moon wrote:


    Now the problem is, if a developer (or me) were to pick up my code and then accidently do myCommand.Execute() instead of MyCommand.Execute()



    Isn't this just a really good argument for not naming private variables exactly the same as properties apart from the case?

  • User profile image
    Jupiter Moon

    JohnAskew wrote:
    

    Of course properties are not an interface as in IUnknown.
    Properties are interfaces for those private data members they provide accessors for.

    Did Anders forget to give properties the ability to hold data? I think not. I think he designed it the way it should be, and not the way you propose because he's thought about it longer and has more experience than we do. I understand the design as is. Introducing having private data inside a property is too close to being a contained class imho, and those cases should be contained classes.

    I'm used to properties from using Delphi, fwiw.



    The way C# implement properties was a great leap forward from Java and C++ etc.  Did Anders cover all bases? I think not, otherwise we wouldn't have C# 2.0 and new versions.

    A class is too semantically different from a property to warrant protecting a variable in a whole class.  The sole purpose of a property is to protect access to a field.  A class is whole different kettle of fish and it is a waste of resources etc. to create just one class with one property in it.  It's a code smell.

    Basically, when you get down to it, the whole job and whole point of a property is to encapsulate a field - it exists only to encapsulate, it is born of the principle of encapsulation, there is no other point to it.  To properly encapsulate it 100% the property should own the field. 

    The point of OOP encapsulation is to seperate concerns or as is sometimes put : "gathering all operations on state into a single interface, and only those operations".  Therefore, to truly encapsulate the field all operations on it's state and only those operations should belong to the encapsulated property. 

    So to  reiterate to finish encapsulating the field we must seperate its concerns by gathering all operations into a single interface i.e. by putting it IN the property. 

    I agree that if you use a private/anonymous class you are keeping to the rules of encapsulation but its still a hack you are forced to use because a property isn't 100% encapsulating the field.

  • User profile image
    JohnAskew

    I just don't appreciate the need to protect private data members from their owning classes.

    If I really need to protect a contained private data member from its container class, I would make that private data a seperate class.

    For me, properties provide accessors, nothing more. They have nothing to do with scoping, that is the job of the programmer.

    My .02

  • User profile image
    jmbledsoe

    JohnAskew wrote:
    I just don't appreciate the need to protect private data members from their owning classes.


    That's exactly what I've been thinking as I've been following this thread.  As far as I can tell, the level of information hiding that OOP suggests is the class level.  If you're the programmer of the class, then it's up to you to work with the private fields correctly.

    On another note, while I have written properties like the one in your (Jupiter's) example, where the private field could be completely contained in the property getter and setter methods, I find that more often I want to use the private field within the class, or I want to initialize it in the constructor, or something like that.

    (that was a long sentence Big Smile)

    I like the fact that you're promoting discussion about extending and expanding the language, but in this case, I don't see enough of a reason to add another wrinkle to the language.

  • User profile image
    jmbledsoe

    Jupiter Moon wrote:
    A class is whole different kettle of fish


    While I'm not sold on the suggested language enhancement, I couldn't agree with this statement more  Wink

  • User profile image
    Jupiter Moon

    jmbledsoe said:
    
    If you're the programmer of the class, then it's up to you to work with the private fields correctly.

    Programmers make mistakes.  Most bugs are programmer’s mistakes and most of them are from working with variables.  In fact, programmers are the biggest cause of bugs there is.  And even if I don’t muck it up someone else, who picks up my code and alters it might.  A good language protects the use of variables as much as possible; this is the whole reason behind properties/generics etc. and being strongly typed.   A good programmer knows he's gonna make mistakes and programs to reduce this as much as possible (see Code Complete).  If languages went on the philosophy of trusting the programmer not to screw up we'd all be hacking perl Wink

    jmbledsoe said:
    
    As far as I can tell, the level of information hiding that OOP suggests is the class level.

    JohnAskew said:
    
    For me, properties provide accessors, nothing more. They have nothing to do with scoping, that is the job of the programmer.

     I don’t agree about scope and information hiding only being at class level; both these statements are incorrect.  C# already supports multiple levels of scoping/information hiding at class level.  For example I can recreate encapsulated properties using scope by doing something similar to the following:

     abstract class BaseClass()
    {
        private string myString;
     
        protected string MyString
        {
             get { return myString };
             set { myString = value};
        }
    }

     public class NewClass() : BaseClass
    {
         public string GetMyString()
         {
              // Will compile
              return MyString;
         }

         public string GetmyString()
        {
              // Will not compile
              return myString;
         }
    }

     
    So C# is fully capable of implementing the feature on a technical level it just doesn’t support the syntax I was proposing.

     

    jmbledsoe said:
    

    I have written properties like the one in your (Jupiter's) example, where the private field could be completely contained in the property getter and setter methods, I find that more often I want to use the private field within the class, or I want to initialize it in the constructor, or something like that.

    I agree for 90% of the code I write (I always, where possible use readonly constructor initialized dependencies).  But for the other 10% where I need to do lazy loading, use Factory method to create object hierarchies with shared objects, do setter dependency injection, wrap resources (files, database connections etc.), use of state pattern etc., my properties need to be a little bit cleverer and need to have a higher level of protection. 

    If you don’t work with these patterns you probably don’t come across the issue much, but if you do you’ll find yourself doing the above abstract class in an hacky attempt to protect your variables from accidentally being walked over.  After all, if a variable is gonna flunk you hope the compiler will stop you (as it does in most instances)!

    On another note: thanks everyone for your replies it seems to be 50/50 for and against.  But I’d like to challenge you:  I’ve heard a lot of personal reasons for disagreeing with the feature (as in you wouldn’t use it) but as far as I can see no-one has come up with an argument to why technically or philosophically it is against either OOP principles (which I think I’ve proved it is more than inline with) or breaks some sort of rule for the .NET framework?

  • User profile image
    PerfectPhase

    why not add a keyword like restricted that means the field is still declared at class level, but can only be accesed from within a property code block?  That way you could have the compiler throw a compile error or warning depending on how strict you want to be?  It also wouldn't mess things up to much if you wanted to access the field via reflection.

  • User profile image
    Jupiter Moon

    PerfectPhase wrote:
    why not add a keyword like restricted that means the field is still declared at class level, but can only be accesed from within a property code block?  That way you could have the compiler throw a compile error or warning depending on how strict you want to be?  It also wouldn't mess things up to much if you wanted to access the field via reflection.


    That does make a lot of sence to me.  Then you're only distinguishing between property level and method level access.

    The only critisism would be on how the compiler would stop other properties accessing the variable (or indeed should it)? And secondly as far as "coding to intent" goes you should keep the variable as close to its usage as possible: though you could do:

    restricted string var;
    private string Var { get; set; }

  • User profile image
    Andrew Davey

    If only C# had syntactic macros like Boo, Nemerle or LISP. Then you could enhance the language in ways specific to your business problem.

    For example, in Boo I could create an AST Attribute to be used like this:

    class Foo:
        [RestrictAccess(Name)]
        private _name as string
        Name:
            get:
                if (_name is null) _name = "foo"
                return _name
       
        override def ToString():
            return _name # This should not compile!

    At compile time the attribute macro scans all members of the class and throws a compile exception if a member not called "Name" uses "_name".

    Maybe one day in the distant future C# will get macros... Smiley

  • User profile image
    PerfectPhase

    Thinking about this some more, sounds more and more like a job for FXCop to me.  Is it possible to write a rule along the lines of if there is a private field _myProp and a property MyProp, warn if _myProp was used outside of MyProp?

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.