April, 2004

Posts
  • Eric Gunnerson's Compendium

    Inherited constructors

    • 23 Comments

    *** inherited constructors

     

    This is a pet complaint of mine - I've never understood why you can't inherit constructors.  People put forth all sorts of arguments against it, but to my mind, they can all be removed by one simple rule: any derived class inherits all constructors from it's parent, if and only if it doesn't construct any of it's own!

    That way, it makes it nice and easy to just "add a function" to a class...

     

    The case where you want to add a function to a class is a fairly rare one. The more common one is where you do something beyond that. In those cases, if we allowed constructor inheritance, then there's a reasonable chance that somebody will forget to do some initialization in a base-class constructor, and then bad things will happen. This is especially bad in the versioning case - if a new version of the base class shows up with a new constructor, you would automatically get a new constructor in your class. Bad.

  • Eric Gunnerson's Compendium

    Efficiency of iteration over arrays?

    • 25 Comments

    I got the following question on email:

    Question:

    Which one of these three loops is the most efficient? How can I prove the answer?

    I've listed the source code below. The three loops are:

    1. Foreach over an int array
    2. Simple for over an int array
    3. For over an int array, hoisting out the length value

    On questions such as these, there are two ways to find the answer. The first is to build the code and look at the generated IL (or the resulting assembly, remembering that you get debug code if you run in the debugger. Attach to a running process, and then you get the optimized native code), or to time the code with a stopwatch.

    In this case, I chose the IL approach, because it was quicker.  For arrays, versions #1 and #2 produce similar IL, and should produce very similar execution speed (I'm too lazy to actually time them today). So, I would choose the foreach version unless I needed the index.

    In fact, I would advocate this position even if for loops are faster, to avoid the sin of premature optimization. It remains true that only 10% of the code needs optimization, and that algorithmic efficiency is often the driving factor.

    The third option is to be avoided. The JIT looks for the pattern in version #2, and knows how to optimize it. If you pull the value out into a temporary, it may not optimize it. Of course, you know that because you've been measuring your important scenarios...

    Code 

    int [] foo = new int[100];
    // version 1:
    foreach ( int i in foo)
      Console.WriteLine( i.ToString( ));
     
    // Version 2:
    for ( int index = 0;
      index < foo.Length;
      index++ )
      Console.WriteLine( foo[index].ToString( ));
     
    // Version 3:
    int len = foo.Length;
    for ( int index = 0;
      index < len; 
      index++ )
      Console.WriteLine( foo[index].ToString( ));
  • Eric Gunnerson's Compendium

    C# Whidbey Featurette #3: Static classes

    • 17 Comments

    Because all functions in C# must live inside of a class, there are some clases - System.Math is a canonical example - that are merely collections of static methods. Since it's useless to create an instance of such a class, in current versions of C#, you can protect against this by creating a private constructor. The constructor can never be called, and therefore no instance can be created.

    There are three issues with this approach:

    1. The private constructor takes up space in the IL, metadata, etc. This isn't a big deal, but it does have a tiny effect.
    2. It's not clear from casual inspection of the source that this class only has static methods.
    3. There's no protection against instance methods on static classes. The compiler will happily let you write methods that could never be called (in theory, a static could call a private constructor and return the instance, but not in this scenario)
    4. You could derive from the class if you forgot to mark it sealed

    So, for Whidbey, we allow the user to mark a class as static, which means that it's sealed, has no constructor, and the compiler will give you an error if you write an instance method.

    Rumor has it that the 1.0 frameworks shipped with an instance method on a static class.

     

  • Eric Gunnerson's Compendium

    const methods

    • 15 Comments

    My number one biggest desire in C#, or complaint (if you choose)...  Are we ever going to see const methods, objects and properties?   I'm one of those who basically think languages we should actually be delimiting non-const items, and having everything default to const, but even though there are work-arounds, not having a const specifier I think encourages people (like me) to be lazy and write really dangerous code!

     

    Const is very hard to do a multi-language environment. You would need to do it as part of metadata, and you would either only do it in some languages (which would reduce its universality), or require every language to support it (not a good thing).

     

    My personal experience convinces me that const is a good idea in the small, but doesn't work too well in the large. Whenever I tried it in C++, I'd always run into the case where a method that was const needed to not be const (and it wasn't a case where mutable would have helped). At that point, I either needed to de-constify all call paths down to that function, or split the api into const and non-const versions. The first is a lot of extra work, and the second will decrease my overall quality.

  • Eric Gunnerson's Compendium

    Acronym of the day: ZBB

    • 11 Comments

    ZBB = Zero Bug Bounce

    As we start moving from the writing code phase into the fixing bugs phase, the development teams start pushing towards zero bug bounce. If you've noticed that the number of blog posts from the C# team has down a bit recently, that's one explanation.

    Why is it called zero bug bounce?

    Well, in the days and hours coming up to the ZBB date, teams will try really hard to get all their active bugs resolved, so they can declare, at one point in time, that they reached ZBB (they should technically say that they reached ZB, not ZBB, but thats not the way it works).

    Reaching ZBB demonstrates two things. First, it shows that you have gotten rid of your bug backlog, and it also shows that your fix rate is greater than your incoming rate

  • Eric Gunnerson's Compendium

    Unsafe and reading from files

    • 6 Comments

    Einar wrote (long ago),

    In the article you wrote on unsafe image processing, you announced a follow-up that would "cover some more unsafe scenarios, including dealing with existing structures on disk". But then I guess something came up, and that article never surfaced (to my knowledge and loss, respectively). How about a blog post instead?

    Einar's first mistake was believing anything that I write about future columns. My track record at getting back to topics is pretty poor - so bad, in fact, that I've tried to stop making promises about what I'll write about next.

    Let's look at some code from a GPS application I've been playing around with for quite some time. This code opens a file and reads a mess of binary structures out of it, and recreates them as real structures.

      public unsafe static GpsDataset Load(string filename)
      {
       GpsDataset dataset = new GpsDataset();

       FileInfo fileInfo = new FileInfo(filename);
       
       int count = (int) (fileInfo.Length / sizeof(GpsPosition));

       using (FileStream fileStream = new FileStream(filename, FileMode.Open))
       {
        BinaryReader binaryReader = new BinaryReader(fileStream);

        for (int i = 0; i < count; i++)
        {
         byte[] buffer = binaryReader.ReadBytes(sizeof(GpsPosition));
         dataset.positions.Add(new GpsPosition(buffer));
        }
       }
       return dataset;
      }

    It starts by getting the size of the file, and then computing how many items are in the file (I could have just read till end-of-file, but that seemed less elegant. Know the size ahead of time allows me to pre-allocate my positions ArrayList (not that I did that, but it *allows me to* do that...)).

    Then it's off to reading the chunks out, into a byte[] buffer. It would be considerably more efficient if I stuck with a stream and read the bytes into the same buffer over and over rather than re-allocated a whole buffer, but a) I haven't gotten around to optimizing this yet b) I wrote it to be flexible, when I didn't know what I'd be storing c) The UI operations are far slower than what I'm doing here and d) did I say it wasn't yet optimized.

    Anyway, this buffer gets passed off to the constructor for GpsPosition, which looks like this:

     [StructLayout(LayoutKind.Sequential, Pack=1)]
     public unsafe struct GpsPosition
     {
      public float AltitudeAboveWGS84;
      public float EstimatedPositionError;

      public float EstimatedHorizontalError;
      public float EstimatedVeriticalError;
      public PositionFix PositionFix;
      public double TimeOfWeek;

      public double Latitude;
      public double Longitude;
      public float VelocityEast;
      public float VelocityNorth;
      public float VelocityUp;
      public float AltitudeAboveMSL;
      public short LeapSeconds;
      public int WeekNumberDays;

      public GpsPosition(byte[] data)
      {
       fixed (byte* pData = data)
       {
        this = *(GpsPosition*) pData;
       }
      }
    }

    The constructor simply fixes the data buffer so it's okay to get a pointer to it, then uses a cast and pointer dereference to copy the contents of the buffer over the struct.

    Note the StructLayout attribute at the beginning of the routine. In it, I set the packing to 1. By default, the runtime will give you nicely aligned structures that are more efficient to access by padding. In this case, I need the structure to match the definition from the Garmin API spec *exactly*, so I have to set packing to 1.

    That's about all there is to it. Define the structure, get a byte[] of the right size, and then copy the data over in a fixed block.

     

  • Eric Gunnerson's Compendium

    Who are the best C# bloggers?

    • 33 Comments
    I'd like to create a list of the best C# bloggers, primarily those outside of Microsoft. Please comment with your choice, and I'll do another post with the full list.
  • Eric Gunnerson's Compendium

    C# Featurette #2 - Inline Warning Control

    • 19 Comments

    Another feature that we added for Whidbey is the ability to selectively disable warnings within your code. For example:

    #pragma warning disable 135

      // Disable warning CS135 in this block

    #pragma warning restore 135

     

  • Eric Gunnerson's Compendium

    Property or backing store from inside a class?

    • 24 Comments

    Josh writes,

    If you've implemented a public property for a private field and you're modifying the field from with-in the class, is it best to use the property, or modify the field directly. For example:

    class Foo
    {
        private object    _Bar;

        public object Bar
        {
            get { return _bar; }
            set { _bar = value; }
        }

        public void FooTheBar
        {
            Bar = new object();

            // or

            _Bar = new object();

        }

    }

    This is an interesting question.

    I generally write all my classes using the backing store, since in my mind, the property is the “outside the object” view, and I'm writing code that's inside the object.

    I might relax this if the property has some additional behavior (ie it's a derived value with no backing store, or there's additional behavior such as “lazy load”), but in those cases I would prefer to encapsulate that behavior in a private method and then use it in both the property and in my location. If you use the property directly, then the class becomes atypical, and that means you might not remember that use when you go to modify the property later.

    Other opinions?

  • Eric Gunnerson's Compendium

    Win32 to .NET Cross Reference

    • 3 Comments

    I haven't seen this referenced before:

    Microsoft Win32 to Microsoft .NET Framework API MapMicrosoft Win32 to Microsoft .NET Framework API Map

  • Eric Gunnerson's Compendium

    Two posers for you

    • 33 Comments

    What is the output of the following code, and why?

    [Update: By “why“, I mean “what part of the C# spec controls this behavior?“]

    class Test
    {
      public static void Main()
      {
        int z = 2;
        z += ++z+5*z++;
        System.Console.WriteLine("Yak! {0}", z);
      }
    }

    What about this code?

    class Test
    {
      public static void Main()
      {
        int z = 2;
        z += (5*z++)+(++z);
        System.Console.WriteLine("Yak! {0}", z);
      }
    }

    Extra credit: What is the defined output for C++, and why?

  • Eric Gunnerson's Compendium

    Jay and Properties...

    • 23 Comments

    Jay wrote a post entitled Properties? Not my bag, baby.

    When I first started writing C# code, I used properties for everything. But recently, I've felt that I was wasting a lot of time writing trivial properties. Yes, I know that in Whidbey I'll be able to use expansions to write them easily, but that still means that I have to deal with the property bodies cluttering up my code.

    So, that got me thinking about whether it makes sense to be writing properties in the first place. After a bit of thought, here's my current position:

    Properties are a great thing for component libraries. There are certainly cases where you would want the future-proofing and decoupling that properties gives you.

    But when you're working on a single project that gets built all at once, I don't think you're getting any future-proofing benefits, and you have to pay the “property tax” the whole time.

    This may be heretical, since “use properties” has been the common guideline.

    What do you think?

  • Eric Gunnerson's Compendium

    Things I wish were better...

    • 9 Comments

    A while back, I wrote the following in a post:

    I continue to be satisfied about the design of C#, but even in our second version, there are a couple of cases in the past few months where we've said, "Well, if we'd been thinking about that when we first did the design, that would be a wonderful way to express that concept, but since we didn't, we're stuck with what we have now."

    There are two cases that come to mind that I think I'll talk about.

    The first - and I'm not positive that it qualifies based on what I said above, but I'd like to talk about it anyway - is the fact that we have both the .Equals() method and operator==() in the language. This situation gets complicated by the fact that there is both reference equality and value equality (sometimes for the same object, such as string), and it's hard to come up with a simple scheme that does both. Having said that, this is an area that I don't think we excelled in.

    The second is a somewhat arcane consideration that isn't especially language-related, but provides a good example of the constraints that timing has.

    The Type class (ie what you get when you use typeof(x) or y.GetType()) has a number of members that describe the type. For example, you can find out whether the type is an array, whether it's a pointer type, etc. In the underlying metadata representation, these attributes are typically encoded into specific bits in the metadata for the type. You can think of this as our primary metadata system, and it was one of the first parts of .NET that was built.

    Somewhat later, we created a second metadata system known as Custom Attributes. Rather than being stored as specific bits, custom attributes are stored as blobs of data hung off a piece of metadata. So, it's puzzle time:

    What is the metadata representation of the following:

    [Serializable]
    class Test
    {
        ....
    }

    This is an example of what is know as a “pseduo-custom“ attribute. Serializable looks like an attribute, but instead of being stored as an attribute, it's stored as a metadata bit, and is accessed through the IsSerializable property on the type object. Which means that if you do typeof(Test).GetCustomAttributes(), you won't get back a serializable attribute. That can lead to some confusion, and in some cases, the reason we're in that state is because we didn't have a full-fledged implementation of attributes early (I'm not sure whether Serializable is one of those cases, but it does demonstrate the issue).

    There are two implementations of pseudo-custom attributes. In the first one, the compiler has special-case code for the attribute, and emits the relevant metadata bits. In the second one, the compiler treats it like any other attribute, and then the runtime removes the attribute at sets the metadata bit. The C# compiler uses both approaches (or at least it did at one time).

  • Eric Gunnerson's Compendium

    RAII and C#

    • 4 Comments

    Daniel wrote:

    I've been reading your blog for quite some time, and, while I love C#, I never understood why it doesn't support RAII (Resource Acquisition Is Initialization). You know, in C++ you can acquire some resource (a handle, a file, a connection) on the class constructor and have it predictably disposed on the class destructor.

    Brian Harry wrote a great post on this a couple of years ago

     

  • Eric Gunnerson's Compendium

    More on ZBB

    • 2 Comments
    Shaykat talks about ZBB
  • Eric Gunnerson's Compendium

    Compiler information as part of code.

    • 12 Comments

    *** #ClassName : gives you the name of the current class

     

    Often I setup loggers and stuff, and always do something like:

    class blah

       static Logger Log = new Logger( "blah");

     

    what I'd like to do is have a context aware statement that got built at compile time (much like the old C++ __line and stuff) -

    eg:    static Logger Log = new Logger( #className )

     

    We've talked about this, but haven't been able to come up with a clean way of doing it. We do understand the value.

     

    *** #member : gives you the name of the member you are in

     

    same as above, it'd be nice to be able to do things like put stuff about what procedure I'm in:

    eg:

    public void Blah()

    {

        Log( #currentProcedure +  ": first line");

    }

     

    ibid.

     

    *** "meta"  parameter definition

     

    This is a little off the wall, but it'd be easy to do, and really cool - have a tag called "meta" which you can put on a parameter - which will actually compile to send information about the actual parameter

    for instance, at the moment I have a thing called EnsureNotMissing( string, object), which just does a "if null throw exception (" parameter " + name + " is missing )

    that means at the moment I have to say

          EnsureNotMissing( "myParam", MyParam );

     

    I would like to build

          public void EnsureNotMissing( object MyParam, meta(MyParam) objectData )

          {

                if (myParam ==null)

                      throw new exception( (objectData as ParameterInfo).name + " is null");

          }

     

    so I can just say

          EnsureNotMissing( MyParam );   - and the compiler will actually throw in the other stuff, like the name

     

    This would be a nice feature. It's something we've touched on obliquely when we talked about __FILE__ and __LINE__

  • Eric Gunnerson's Compendium

    I'm 28 today...

    • 11 Comments

    On my post about “particular boats and funicular goats”, Steve properly surmized that it was birthday related. It comes from the groundbreaking Dr. Suess book “Happy Birthday to You”, which I think is Geisel at his best. Long sentences, wonderful rhymes, and a real challenge to read well. Luckily, I have the excuse of having a 9 year-old-daughter, so I can still read Suess.

    So, what am I doing to celebrate? I started at 6:30 with a bike ride (35 degrees, but beautifully sunny), then came home, ate, and came in to work. I've just finished my part of a presentation (more on that in another post). This afternoon one of my friends (Hi Nick) is flying in for the MVP summit, and we're heading up to my ski cabin for the weekend.

    I'm not sure whether I'm going to buy myself a present yet. I've been thinking about buying myself a Twilight Zone, but I haven't found one I like yet.

    Oh, and that's 28 Hex

  • Eric Gunnerson's Compendium

    C# MVP Feedback session

    • 8 Comments

    On Tuesday night, I spent a bit of time at the MVP party (good company, not a great party), and then went home to work on slides. Scott had gathered some MVP feedback, and it was my job to condense it into some summary slides to drive the discussion.

    I polished the slides this morning (about two days too late for my taste), and then did the presentation to the MVPs this morning. It took me a few minutes to get back into feedback mode, but then I talked for about 90 minutes without a break.

    I know that the C# are MVPs are talented, but I'm always amazed how insightful they are. We are very lucky to have them.

    Doing this sort of customer feedback session is one of my absolute favorite things to do. It took me arond 35 years (and a bit of work on my part) to discover that rather than being a fairly shy person, I'm actually a bit of a ham when I get up in front of a group. Customer feedback sessions are great because I can ad-lib my answers, and I like both the challenge and the comedic potential in such an interaction.

    I always learn something new in such a session. One of the MVPs commented that if there was an organized group of C# MVP blogs, that would be one good way to get insight into what MVPs were thinking about. What a great idea.

    Thanks to all the MVPs for coming to Redmond to talk with us, and for all the C# work that they've been doing. Their impact on the C# community is immense - whether it be on a newsgroup, on a website, through training, or through online content.

  • Eric Gunnerson's Compendium

    Pragmatic Unit Testing in C# with NUnit

    • 3 Comments

    I got this reference from http://www.theserverside.net, but since they require login to get to the link, I'll instead refer you to the book page

    I took a look one of the sample chapters, and I thought it looked pretty good, except for the fact that the first interface in the chapter is named “Environment” (the others are fine). 

  • Eric Gunnerson's Compendium

    My presentation today

    • 6 Comments

    This morning I presented at a community review for my manager, my second level, my third level, and my fourth level (one of the MS VPs). The review is about how our division is doing on community overall, and I owned talking about some of the things that we've been doing on the C# side (blogging, FAQ, etc.)

    I was a bit nervous when I was on the way to the presentation, but I've found that if I do good walkthroughs ahead of time, once I start presenting, I'm focused on the presentation and I don't even think about being nervous.

    Of course, the 8 hours I spent on writing slides and practicing helped.

    So my guidance is

    Never present in front of an important group of people without having practiced your talk at least twice.

  • Eric Gunnerson's Compendium

    Gunnerson's rule of the internet

    • 8 Comments

    No matter how strange or bizarre a hobby, there is always a web page devoted to it.

    Presented for your enjoyment: example #231. Make sure you look at the embedded picture below.

  • Eric Gunnerson's Compendium

    Rico writes on improving .NET application performance and security

    • 3 Comments

    Rico writes an interesting forward.

    I mention it for 3 reasons:

    1. Rico generally writes good stuff
    2. I agree with him
    3. Rico respects my talents, in that he was one of my original interviewers at Microsoft many years ago and didn't say that he would quit if the C++ team hired me. Or if he did, he's been nice enough not to say anything since.
  • Eric Gunnerson's Compendium

    "Close to being Released"...

    • 2 Comments

    Scott wrote in reference to something I said...

    A year away is “close to Whidbey being released”?

    Well, yes. My meaning was inteded to be “close to released for Beta”, but in terms of the final functionality that we'll deliver, Beta1 will be relatively close to what the final bits are.

  • Eric Gunnerson's Compendium

    Poser update

    • 12 Comments

    A few updates on the results of my “poser” post.

    First, anybody who said “anybody who coded that deserves whatever they get” is absolutely correct, but gets no points because that wasn't the answer we were looking for.

    I thought it was an interesting question for two reasons (most of which Wes covered in his response, but you may not have read it).

    First, when you write:

    x += 5;

    the compiler write this as

    x = x + 5;

    which obviously changes the order of evaluation, and the answer to the question.

    The second is that C# evaluates from left to right, so you can reason about how expressions are evaluated.

    In C++, it's implementation-defined, and you truly get what you deserve.

  • Eric Gunnerson's Compendium

    How a bug becomes a fix...

    • 2 Comments

    Anonymous Corporate Coder wrote a comment on my ZBB post, asking what set of bugs ZBB relates to.

    I started to update that post, but it quickly expanded, so I've decided to write a separate post.

    We're organized around a milestone approach. Some milestones are date-driven, some are quality-driven, and some start as quality driven and change to date driven.

    As we code through a milestone, all bugs belong to that milestone, and as we start to push towards ZBB, we will be tracking all those bugs. At some point along the march to ZBB, we will start moving some bugs to a later milestone if there is one, or postpone them for this product.

    Whether a bug gets moved or not depends upon a lot of factors. If we're quality driven, we will punt fewer bugs beyond the milestone. If it's the last milestone of the product (RTM), we punt fewer bugs. We have an elaborate way of describing whether bugs are fixed or not (Gus, if you're reading this, how about a post on bug bars?).

    That will get us to a set of bugs we believe should be fixed in a specific milestone, and we drive to get that fixed.

    On the C# compiler team, we try not to punt bugs, especially if its the last milestone.

     

Page 1 of 2 (39 items) 12