Just a small post to say goodbye as I'm leaving for one month of holidays in the far Peru for a trip between Lima and Cusco.
It will be very nice and relaxing ! See you soon !
Today, my colleague Thierry Thoua has shown me a bug in one of the .NET framework class. If you look in the Lutz Roeder's Reflector for the CompilerType.Equals method, you should see something like:
public override bool Equals(object o)
{
CompilerType type = o as CompilerType;
if (o == null)
{
return false;
}
return ((((this._codeDomProviderType == type._codeDomProviderType)
&& (this._compilParams.WarningLevel == type._compilParams.WarningLevel))
&& (this._compilParams.IncludeDebugInformation == type._compilParams.IncludeDebugInformation))
&& (this._compilParams.CompilerOptions == type._compilParams.CompilerOptions));
}
what happens ? Of course as they do not check "type" for nullity, but for "o" instead, you may have a NullReferenceException. Apparently he has seen such a bug in some other classes in the .NET framework. Maybe some more information on his blog ?
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()
{
myValue = 10;
}
}
and proposed us to migrate it to that
class UsingAutoImplementedProperties
{
public int MyValue { get; set; }
public UsingAutoImplementedProperties()
{
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);
}
}
}
}
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()
{
MyValue = 10;
}
}
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
-
Calling the constructor of the class
-
Calling the need for building the base class
-
Initializing the variables of the base class
-
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.
For once, a non .NET post :-)
I have bought recently a new laptop, a DELL Inspiron 1720. Quite a nice laptop in fact. The only thing is that I bought with it Windows Vista Professional and that I was not completely ready for the change. Anyway, note that DELL will stop its support of Windows XP very soon, in June I think. Anyway, the point is that I wanted to re-install Windows XP on it. No problem ! Let's go for it !
First trial of installing Windows XP
-
Let's have a look on the drivers I was needing. I have heard before that some graphic card were using DirectX 10 which doesn't exist on Windows XP. So far so good, it's not the case of my nVidia card. And on the website of DELL, I can find the drivers of all my hardwares components. And even better, the resource CD they sent to me contains the drivers for Windows Vista AND for Windows XP ! (Note that a bit later on, I will find that it doesn't contain the drivers for my video card, sound card, and bluetooth. So you should download some from the DELL website)
-
As I have a long past with DELL computers, I also have a bunch of DELL Windows CDs, including a Windows XP SP2. It would be better with SP3 but ok. I can live with that.
-
Let's boot on it and start the installation !
-
Of course, it does'tn work. I do not have any hard driver ! The reason is simple : the recent computers have SATA drives that are not recognized by Windows XP. So what can I do ?
Let's create a new Windows CD
The first proposal may work but I didn't tried it. However, creating a new Windows CD was seducing as I could also add the SP3 !
-
Let's download and install a free tool named "
NLite". It's a tool that will allow us to create our CD
-
Then let's copy all the content of out original Windows CD (XP Pro SP2 in my case) in a local folder
-
Launch NLite and choose your language, then click on "Next"
-
Select the folder of your local copy of your Windows CD
-
Click on Next
-
As it is the first time you are doing this, you do not have any previous session, simply click on Next
-
Choose which operations you will want to do, in my case, I have selected
-
"Service Pack" as I want to migrate from SP2 to SP3
-
"Drivers" as I want to include my "Intel AHCI" drivers
-
"ISO bootable" as I want to boot from my CD to install Windows
-
Click on "Next"
-
Select the Service Pack you want to include (simply select the ".exe" file. Nlite will uncompress it and will integrate it to the local content)
-
Click on "Next"
-
Integrate your new drivers
-
You have downloaded from the DELL website (or extracted from the resource CD) you hard drive SATA drivers. Just launch the exe to uncompress it in a temp folder
-
Click on "Insert / simple driver" and select the uncompressed ".inf" file. In my case it is : "iaahci.inf"
-
Select all the drivers that are available (a simple ctrl + A) and click "OK"
-
Click on "Next"
-
Click on "OK" to launch the creating of the new CD (in memory for now)
-
Click on "Next" and now you have the possibility or to burn a CD or to simply create an ISO for later use.
-
I just decide to create an ISO I will burn with Nero later on
Second trial of installing Windows XP
Now I do have my new CD ready so I can simply boot on it to install right ?
-
Let's boot on it
-
Great now Windows recognizes my two hard drives... !
-
...and also show me 4 partitions on my C: drive... well I had seen only 2 via Windows (my OS partition and a restore partition)
-
Ah yes... this DELL laptop has been preinstalled with "DELL Media Direct" !
-
Let's do the same
Preparation of hard drives for DELL Media Direct
-
Just to start from a clean system, I have decided via the Windows installation to delete all the existing partition on the C drive, just to let a 200 Gigs of unpartitionned space
-
Just restart and boot on your "DELL Media Direct" CD you have received
-
Note that this preparation would delete anything oon your hard drive. In my case, as I have deleted my partitions, it's already done... but be sure to do that before any other installation !
-
Now a choice to do !
-
Select "1" if you want to have a single partitions on your C drive. In that case, the DELL Media Direct installation will create two other partitions for him and will let you with a single big other one
-
Select "2" if you want another partition (typically your OS partition and a Restore / Data / ... partition)
-
And what do I need to select if I want more partitions ? well you can't... A little bit of "Partition Magic" later on ?
-
And that's all. Now you are ready to go
Last trial of installing windows XP
-
Now you can reboot on your Windows XP CD to install it !
-
Note that you MUST install Windows XP on your C drive, the drive where DELL Media Direct has created its partitions
-
When finished, you will need to re-put you Dell Media Direct CD to complete the installation also
-
And here you are with the installation of all your drivers !
I have given here some clues about creating control adapters. A few days after I have started to use them, I have encountered some very special problems. In fact the adapters have the following hierarchy : the .NET framework expose a ControlAdapter from which derives a WebControlAdapter and a PageAdapter. THe name of these classes being explicit enough to let you know in which cases you should use which one.
As a consequence, when you want to adapt a WebControl, you should use a WebControlAdapter or one of its derived classes. So far, so good, so simple.
But what you should know is that the framework expose in the WebControl class a method called Render. Never seen it or overriden it ? Normal it's a protected internal one. This method is responsible of the rendering of the control and so does : RenderBeginTag, RenderContent and RenderEndTag. And these are the three methods you will normally work with.
And so what does the WebControlAdapter : it will redefine the Render method to do the same work : RenderBeginTag, RenderContent and RenderEndTag. And each of these methods will either call the apdater's equivalent method, or the one of the control itself.
Pretty normal. No problem there.
Well... Almost... Let's imagine just one moment, that someone has defined some other code in the Render method ? Well... That would bring some troubles no ? Right it would break the .NET standard but let's imagine. Of course, in that case, using a WebControlAdapter would just bring a you a no-longer working control.
It's in fact what happens in the BaseValidator class (which inherits from WebControl of course). The Render method does a lot more, like rendering javascript, the "display" and "visibility" attribute.
Which conclusion, what can we say now ? Never use a WebControlAdapter when working with a BaseValidator (or any derived class). Prefer working with a ControlAdapter instead !