juin 02

A few time ago, one of my colleague has seen the following code

class UsingVariable
{
   private int myValue;
 
   public int MyValue
   {
      get { return myValue; }
      set { myValue = value; }
   }
 
   public UsingVariable()
   {
      // Let's set some default values
      myValue = 10;
   }
}

and proposed us to migrate it to that

class UsingAutoImplementedProperties
{
   public int MyValue { get; set; }
 
   public UsingAutoImplementedProperties()
   {
      // Let's set some default values
      MyValue = 10;
   }
}

argueing /explaining that now with the .NET 3.5 new features, it was possible, and as the local variable was not usefull, we could get rid of it.

When he told that I had a strongly opposed reaction. We should not do that. The local variable is not usefull ? And what about if the property was harmfull ? Let's see what could happen.

Comparison of the two codes:

Well nothing really to see. The code are currently perfectly equivalent. They will behave the same. Some purist may tell that the second is "slightly" slower (as using a call to property, ie to a method). Well... This is perfectly negligeable.

So these two codes are equivalent. I would precise : these two codes are equivalent... at the condition you assume your code will never get touched and changed in the future. And I'm not sure this is a bet an english bookmaker would do.

Let's see two possible evolutions and check what would happen.

Evolution 1 : some event raising in the property

You all know that for an auto-implemented property, both the get AND the set must be auto-implemented. As a consequence, if you need / want to do some extra treatment in one of the two, you will need to get rid of the auto-implementation to do it yourself. What could happen ? Let's imagine something like :

class UsingAutoImplementedProperties_Evolution1
{
   private int myValue;
 
   public int MyValue
   {
      get { return myValue; }
      set 
      {
         if ( myValue != value )
         {
            OnMyValueChanging(EventArgs.Empty);
            myValue = value;
            OnMyValueChanged(EventArgs.Empty);
         }
      }
   }
 
   //Other implementation ommited
}

We'll simply follow some .NET conventions to raise an event when the property has been changed. Well is that impossible ? Far from that I think.

What may happen ? Well, an event may be raised to indicate to a client that the internal state of the object has been changed. And the client may do some treatment on the object whose internal state has changed. Well yes but on which object really ? On that object I'm manipulating and on which I'm still not finished with the constructor ? Meaning on that object that may have any incorrect or un-initialized values ?

We can just smell there is something going wrong here.

Note that this case may not happen in real life. If I want to handle the event, I will need to have an instance no ? Right. Anyway, this example - not realistic but not so far from real life - let us smell and glimpse there may be some tricky problem to find out there.

Evolution 2 : Adding a level of hierarchy

Let's imagine we need to add a level of hierarchy in our class. We'll simply put for example the property as virtual.

class UsingAutoImplementedProperties_Evolution2
{
   public virtual int MyValue { get; set; }
   public UsingAutoImplementedProperties_Evolution2()
   {
      // Let's set some default values
      MyValue = 10;
   }
 
   //Other implementation ommited
}

And let's create any derived class, let's imagine like this.

class DerivedClass : UsingAutoImplementedProperties_Evolution2
{
   private OtherClass objectInitializedInCtor;
 
   public DerivedClass()
   {
      objectInitializedInCtor = new OtherClass();
   }
 
   public override int MyValue 
   {
      get { return base.MyValue; }
      set
      {
         objectInitializedInCtor.DoSomething();
         base.MyValue = value;
      }
   }
}

What is the consequence ? When I will do a new DerivedClass(), here is the workflow that will occur (I will simplify it by giving only the steps related to the code example) :

  • Initializing the variables of the class
    • Here, setting objectInitializedInCtor to null
  • Calling the constructor of the class
    • Meaning here doing nothing (for now) as we have a level of inheritance
  • Calling the need for building the base class
  • Initializing the variables of the base class
    • Here, setting the backing field of the MyValue property to 0
  • Calling the constructor of the class
    • Calling the property MyValue to set 10
    • This will in fine call the property MyValue of the derived class
    • This will call the method DoSomething on the objectInitializedInCtor (which is null)
    • This will crash 

This case is pretty simple as it will crash. Let's imagine now we are dealing with a collection that has been created, but not yet filled in, or on some values that still have their default value instead of the real one, this may cause very tricky bugs to find out.

Is that bad ? It's not my code...

What can we see here ? The application may crash / bug not because of the original code, but because of the evolutions we may bring to this code. The question may be "who is responsible for the bug ?".

Well in my view, the responsible is for sure the first code and NOT the evolution. Indeed we have assumed that our code WILL NOT evolve, and so we have put in place un-needed risks. And the guy making the evolution has just made a simple evolution, touching simply what he would need, and not more. I would even say, just what he was supposed to touch.

Imagining that the original code will not take this risk, is that defensive programmation ? Not in my view. For me defensive programmation is putting many things in place, because we thing the next one will add some bad / buggy code. Here it's the contrary, it's just writing the code to avoid having the next developper needing to think the ones before has written some bad / buggy code.

Does this resolve everything ?

No of course. But before detailing any other aspects related to the risky original code, or to the proposed code (ie without using properties in the constructor), I would like to listen to the reactions of all of you. To know what you think on the subject and which limitations you see.

Tags: | | | |

Commentaires

Steve Degosserie

Posted on lundi, 2 juin 2008 10:24

Hi Pierre-Emmanuelle,

This case is interesting as it demonstrates that a new feature of .Net 3.5 (Automatic Properties) while it brings some added productivity (less code to type), it also brings a higher risk of fragile code, if the developer is not carefull.

Concerning the second example you mention (change of behavior in subclass), it makes me think about the Liskov Substitution principle (en.wikipedia.org/.../Liskov_substitution_principle), which states that "if S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that program".

This leads to another debate ... if you are unsure about possible side effects that could be added in subclasses of you classes, should you seal all classes by default, and only open them (un-seal) whenever necessary ? ;)

phen375 cheap

Posted on lundi, 10 juin 2013 23:26

When I initially commented I clicked the "Notify me when new comments are added" checkbox and now each time a comment is added I get three e-mails with the same comment. Is there any way you can remove people from that service? Thanks!

Also visit my web blog  phen375 cheap - http://safephen375.com

phen375 buy

Posted on mardi, 11 juin 2013 14:19

Its like you read my mind! You appear to know a lot about this, like you wrote the book in it or something. I think that you could do with a few pics to drive the message home a little bit, but other than that, this is magnificent blog. A fantastic read. I will certainly be back.

Here is my blog post ::  phen375 buy - http://www.importantnews.ca/NoreenKerr

http://www.wiki.dashengjiao.org/index.php?title=%E4%BD%BF%E7%94%A8%E8%80%85%E8%A8%8E%E8%AB%96:BroderickCapra

Posted on vendredi, 18 octobre 2013 03:13

Spot on with this write-up, I honestly feel this site needs far more attention. I'll probably be returning to read through more, thanks for the information!|

Also visit my page; pit38;  http://www.wiki.dashengjiao.org/index.php?title=%E4%BD%BF%E7%94%A8%E8%80%85%E8%A8%8E%E8%AB%96:BroderickCapra - http://www.wiki.dashengjiao.org/index.php?title=%E4%BD%BF%E7%94%A8%E8%80%85%E8%A8%8E%E8%AB%96:BroderickCapra ,

pure garcinia cambogia

Posted on jeudi, 31 octobre 2013 01:11

If you want to get much from this article then you have to apply such strategies to your won weblog.

Feel free to visit my blog;  pure garcinia cambogia - http://geneessence.com

where to buy natural garcinia cambogia

Posted on jeudi, 2 janvier 2014 13:11

Attractive element of content. I just stumbled upon your website and in accession capital to claim that I get in fact enjoyed account your blog posts. Anyway I will be subscribing for your feeds and even I success you get right of entry to persistently quickly.

Take a look at my web site;  where to buy natural garcinia cambogia - http://blogs.albawaba.com/eltonbarksdale

Ajouter un commentaire




biuquote
  • Commentaire
  • Aperçu immédiat
Loading