Archive for January, 2010

Is There A Good Reason To Hide Inherited Members?

22 commentsWritten on January 17th, 2010 by
Categories: C#

A mistake that i used to see a lot, and sometimes still do, is that developers hide inherited members in derived types.  For those of you who don’t know what that means, check out the following class:

    public class MyClass

    {

        public void DoSomething()

        {

            Console.WriteLine("i'm doing something important");

        }

    }

 

As you can see, the DoSomething method does something important, so you as a developer should consider its behavior important as well.   In some cases, you might want to add something extra to this behavior in a derived class.  Some developers would do that like this:

    public class MyDerivedClass : MyClass

    {

        public void DoSomething()

        {

            base.DoSomething();

            Console.WriteLine("(i'm just better at it)");

        }

    }

 

When they compile this, they’ll get the following warning:

warning CS0108: 'HidingMethods.MyDerivedClass.DoSomething()' hides inherited member 'HidingMethods.MyClass.DoSomething()'. Use the new keyword if hiding was intended.

When this occurs, either one of 4 things can happen:

  1. The developer doesn’t bother to read compiler warnings (an offense worthy of a bitchslap) and is not aware of a possible problem
  2. The developer sees the warning and just adds the ‘new’ keyword to the method.
  3. The developer reads the documentation to figure what this really means, and hopefully realizes his mistake.  If he does, he combines this option with option 4.  If he doesn’t, he goes the option 2 route.
  4. The developer realizes his mistake and either makes the base method virtual and adds the override keyword to the method in the derived class, or when that’s not possible, either renames the method or thinks of a different approach.

If you’re unlucky, you either end up with no modification or the method will now look like this:

        new public void DoSomething()

        {

            base.DoSomething();

            Console.WriteLine("(i'm just better at it)");

        }

 

Great, no more compiler warning! All is well in the world now, right?

Err… not really.

The DoSomething method of MyDerivedClass actually hides the original DoSomething method. 

The following code will always produce the expected behavior:

            new MyClass().DoSomething();

            new MyDerivedClass().DoSomething();

 

That is, when the DoSomething method of an instance of MyClass is called, it will obviously execute the original DoSomething method.  And if the DoSomething method of an instance of MyDerivedClass class is called through a reference of MyDerivedClass then it will call the ‘new’ DoSomething method.

The following code however, would not produce the expected behavior:

        static void DoIt(MyClass subject)

        {

            subject.DoSomething();

        }

 

        static void Main(string[] args)

        {

            DoIt(new MyClass());   

            DoIt(new MyDerivedClass());

 

            Console.ReadLine();

        }

 

In this example, the DoSomething method is always called through a reference of MyClass.  When the DoIt method receives an instance of MyClass, the original DoSomething method will obviously be executed.  What some (many?) people unfortunately aren’t aware of is that when an instance of MyDerivedClass is passed into the DoIt method, the ‘new’ DoSomething method will not be executed but only the original one will be executed.  The reason is because methods that hide inherited members can only be called through references of the type, or derived types of that, that hides the inherited method.  Doesn’t really sound like a fun situation to debug, right?

So anyways, back to my original question: is there any valid reason why you would want to do this? Or better yet, can you share a situation where you had to resort to hiding an inherited member and if so, are you happy with the solution or did you consider it a hack?  And are you aware that it is essentially a bug waiting to happen?

So far, i have never actually seen a valid reason for doing this.  The only reason i’ve seen so far for occurrences of hidden members was because the developers that used it simply didn’t know any better.  In some cases, either me or someone else wasted debugging time on this when a piece of code that used a reference of a base class suddenly didn’t do what was expected when it was passed an instance of a derived class which hid the original method.  

I have read of only one valid reason to do this, and that is if a (either virtual or non-virtual) method with the same signature is introduced outside of your control in a base class that you can’t modify (like say, a class in the .NET framework or some other 3rd party assembly that you depend on) and you want to get rid of the compiler error that you got when recompiling against the newer version of the assembly.  In that case, it does make sense though i’d still say it’s going to be a future source of confusion sooner or later, and quite likely lead to a future bug as well.  In that situation, i’d much rather rename the member in my class.  Even if it means that consumers of my code will be forced to deal with the breaking change.  After all, a simple rename will always be less work than having to debug an issue because of a hidden member.

This Is Just Not Cool

5 commentsWritten on January 15th, 2010 by
Categories: Rants

not_cool

That’s what happened when i ran the RunMeFirst.bat file that comes with the NServiceBus download. 

What if i actually need msmq_ADIntegrated?

Career Advice For Young Developers, Part 2

5 commentsWritten on January 13th, 2010 by
Categories: Opinions, work/career

Little over a year ago, i wrote a post which had some career advice for young software developers. That post was mostly based on things that worked for me, but obviously also on mistakes that i had seen other people make. Now, a large percentage of posts in my 'Opinions' category are directed at people that i know personally, and this one is no exception. I typically don't mention names or actual situations in those posts, but in this post i am going to talk about a certain situation, though i won't name names. I am going to contact the person in question so he knows full well that this post is directed to him. If he doesn't like that, that's his problem. Hopefully, he'll appreciate the advice though.

Every year we work with interns from the school that i and many of my coworkers come from. We've been extremely lucky with the interns we've gotten from that school so far, and many of our best developers actually come from that school. We basically expect to get really good people from them and when they do good during their internship, they usually get offered a job and most of them accept it. Last year, we had 5 interns from that school. Two of them are now working for us. There was another guy who i would've loved to have on our staff. This kid was 21 (maybe 22, not sure) years old, and i quickly noticed that he was exceptionally talented. I don't know about you guys, but i rarely get to talk with anyone who really makes a great impression on me (on a technical level) who i'm not already working with or who i've haven't worked with in the past. I was very impressed with this kid even before i saw his code. He knew a lot of stuff that most of us only learn after a while, and he seemed to be a very all-round talent.

I was very curious to see how he would complete his internship and i was already hoping that he would be working for us once he graduated. He took on a leadership role of his team (which admittedly, consisted only of interns) but he really managed them pretty well. He took care of most of the technical challenges, and he made sure the others were productive in their tasks. If he wasn't sure of certain technical issues, he didn't mind asking for advice or help. The skills and the approaches he demonstrated at his age were truly exceptional in my opinion. No matter how good you think you are right now, think back about how you were when you were 21, 22 years old. I thought i was pretty good back then, but i didn't even know a fraction of what i know right now. And i don't just mean on a technical level, but more about how businesses work, how you need to deal with people and situations, stuff like that. Most people simply don't have a clue about how to deal with that at that age.

This kid knew, though. Not everything obviously, but at least a lot more than most people would at that age. He's smart, he's talented and he knows how to apply his skills. The one thing he doesn't know yet, is how to deal with previous mistakes. And that is something you only learn once you've been working in a professional environment for a year or two, and if you're lucky enough that people will challenge you and confront you with your mistakes. He may not have liked it, but i once caught him breaking the build and i told him he needed to fix it. He said it was a problem with subversion and that something must've gone wrong with the commit in question. I showed him that it was impossible that it could've been due to a problem with subversion and that he simply made a mistake in his commit. And while he probably still won't admit it, he knew that i was right and that he was wrong. Now, there's nothing wrong with a situation like that per se, but it was clear that he wasn't used to a situation like that.

Think about it. You're gifted. You've got a lot of talent. You're pretty much better than anyone you've ever had to deal with at school. But the thing is, true improvement comes from learning from your mistakes, and you need to be in a situation where people aren't afraid or too intimidated by your skills to be able to tell you when you're wrong. If you don't get confronted with your own mistakes, you are going to miss out on a lot of opportunities to improve yourself.

This guy made it very clear from the beginning that he wanted to pursue another degree after he graduated. And he's currently doing that. The thing is, with the skills that he has, and the ability to convince other people of his skills, combined with the extra degree that i have no doubt he'll earn this year, it's very likely that he is going to end up with some large company in a very comfortable position. The thing that worries me though, is that a lot of people in those kind of companies aren't very honest with their employees. Especially the ones they consider to be 'high-potentials'. I doubt that he's going to be around the kind of people who are going to be honest with him when he makes mistakes (and he surely will make them, as everyone does). And no matter how good you are, no matter how well you learn from your own mistakes, a very large part of self-improvement comes from being confronted with your mistakes by others.

So finally, we get to the 'advice' part of the post. To him specifically, and anyone else who recognizes himself (or herself) in a story like this i would advise the following:

  • Do not automatically assume that a fancy position at a large company is the best situation for you. For most of these companies, you're only valuable as long as you're willing to play along with their game. It's their game, their rules. You either play along, or you fold after a while, and believe me when i tell you that it is going to end up bothering the hell out of you.
  • Learn to appreciate criticism. If you handle it right, you're only going to end up better from it and you will truly learn from it.
  • Status or position doesn't mean anything if you suddenly realize you're surrounded by idiots.
  • If you don't really need the extra money you can make while working for people who truly couldn't care less about you personally, you certainly don't need to subject yourself to all of the crap that will come with it.

OMG! Someone Stole My Code

7 commentsWritten on January 12th, 2010 by
Categories: Opinions

I received an email from someone who wanted to let me know that she noticed that a coworker of her used all of the code from my Build Your Own Data Access Layer Series in their project without any notice of where it actually came from. The code in that series was posted using the Creative Commons Attribution license which only states one simple condition:

You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work).

First of all, i don't really get what this person was trying to achieve by notifying me of this. What am i going to do about it? Ask them to add a notice? Should i even care about it? I don't, actually. If anything, i'm glad they're using it and i just hope that it works for them and that they don't run into any issues with it. If i didn't want people using it, i shouldn't have posted it. And as for adding a notice... that would be nice, but it's not going to make any difference for me whether they do or don't.

I think it's different when you release code as an open source project. Then i obviously do want people to respect the license, but for blog code i don't really care what people do with it. I did mention a license in the original post, but that's pretty much only because some people don't want to use it if there is no license mentioned. Which is correct, theoretically. But the vast majority of code that i list on this blog never has a mention of a specific license. It's just too much of a bother IMO, and there isn't anything that i can realistically do about it if people use it without respecting the license anyway.

So for future reference: feel free to do whatever you want with any code that i post on this blog, unless of course that code comes from an open source project. Would it be legal? No. Am i going to do something about it? No.

Checking Whether A Method Is Overridden

13 commentsWritten on January 11th, 2010 by
Categories: C#

One of the requirements for using Agatha’s Caching Layer is that your request types must override the Equals and the GetHashCode methods.  In order to limit the number of questions i’m going to receive about the caching layer not working correctly the amount of time people will waste on debugging when they don’t override these methods, i wanted to add a check to the initialization of Agatha which makes sure that each cacheable request type indeed overrides Equals and GetHashCode.

I actually had to think about how i could do this, but it turned out to be very simple.  The trick is basically to retrieve the MethodInfo of the method you're interested in, and then check the declaring type of that method.  If the method has been overridden, the declaring type will equal the type of the class you're checking.  If it hasn’t been overridden, the declaring type will be that of one of the base classes:

        private static bool CheckIfOverrideExists(Type type, string methodName)

        {

            var methodInfo = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public);

 

            if (methodInfo == null)

            {

                return false;

            }

 

            return methodInfo.DeclaringType == type;

        }

 

Not sure if there’s a better way to do this (if so, please share) but for now, this is good enough for me.