April, 2004

Posts
  • 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

    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

    Video killed the blogging star...

    • 6 Comments
    Or at least it may. Take a look at this and this.
  • 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

    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

    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

    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

    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

    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

    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

    Attributes that take parameterinfo or methodinfo

    • 3 Comments

    *** typeof( x.y ) gives you propertyInfo/MethodInfo

     

    We are making all sorts of cool framework things, using reflection and attributes.  They are all great, but we've found a few places where we want to specify properties/methods in other classes, as arguments to attributes - (for instance - the value of this calculated field depends on the value of this other field).  It would be really nice if the typeof operator could return a methodinfo/propertyinfo object!

     

    To do this we would have to extend the attribute scheme to support new kinds of information, and that would require all the languages to add support. I think it would take a fairly compelling argument to do that. I don't think that changing Type to also be able to point to methods or properties is feasible.

  • Eric Gunnerson's Compendium

    Allow using up to the object level.

    • 16 Comments

    Darren sent me a few questions. Normally, I'd put these in the C# FAQ, but I've decided to answer them here for now. They may migrate to the FAQ in time.

     

    *** allow "using" up to the object level

     

    I use VB sometimes, and one of the things I really love about it is that if I create a static class (say CommonFunctions)  I can import SMB.Common.CommonFunctions.  All static functions are now part of just my standard namespace.   I like it!  Object purists may have collective apoplexy, but I'd prefer to remain agnostic and believe that we shouldn't have to qualify absolutely everything we do.  Some functions really do belong in the global namespace (and all languages have some) - and it would be really nice as a developer to be able to make our own.  It's there in VB - can we have it in C#?  Please? :)

     

    I think it's unlikely that we will do this. I understand the desire to be able to do this, but one of our major goals is to keep the language readable. Features like this and C++'s macros mean that to read code, you don't just have to understand the base language, you also have to understand all the additions that have been added by the author of the current project.

     

    So, yes, it is true that writing Math.Sin() is longer than just writing Sin(), but it's also much clearer to any reader of the code.

  • 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

    PInvoke.Net

    • 5 Comments

    If you've ever wished you could find a P/Invoke definition for a Win32 function, you'll like this site.

  • 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

    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

    More on ZBB

    • 2 Comments
    Shaykat talks about ZBB
  • 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

    I'm a winner!

    • 13 Comments

    We are pleased to inform you of the announcement today the 3rd , 2004 of winners of the SCIENTIFIC GAME PROMO LOTTERY; THE NETHERLANDS / INTERNATIONAL, PROGRAMS held on 4th March, 2004. Your email address attached to ticket number 042-82156178051, drew the lucky numbers 6-12-18-22-44-59,batch number 7432/NL and consequently won the lottery in the 1st category. You have therefore been approved of a lump sum pay out of EURO 1,500.000.00 Euros (ONE MILLION FIVE HUNDRED THOUSAND EURO) in credited to file LOTTERY REF NO. SYWA/548802/04

    Oops. looks like I violated the agreement:

    Due to the mix up of some numbers and names, we ask that you keep this award strictly from public notice until your claim has been processed and your money remitted to your account. This is part of our security protocol to avoid double claiming or unscrupulous acts by participants of this program.

    “unscrupulous acts“. I like that part the best...

  • 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

    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

    Taking it to the next level...

    • 6 Comments

    Josh writes:

    I've been working professionally with C# for about 2 years now and am just blown away by the things I can do with it. Lately though, I've felt like I've plateaud at this beginner to intermediate level. Every book I look at is either "Hello, World" or beyond my level of expertise, I feel like I'm always one step behind the game and my code is becoming stale.

    That's a very interesting question. I'm not longer a professional programmer (though I was for a little over a decade), so you'll also want to listen to the comments that others are sure to write.

    If you haven't read them, there are a couple of books that I'd definitely recommend.

    Code Complete
    The Pragmatic Programmer

    Both of these are currently on my bookshelf (actually, they would be if somebody hadn't walked off with my copy of Code Complete).

    To expose yourself to some new ideas, I'd also suggest:

    Refactoring: Improving the Design of Existing Code
    Extreme Programming Adventures in C#
    Test-Driven Development in Microsoft .NET

    Whether you agree with these approaches or not, they are certainly thought-provoking.

    The best programmers that I've known always have a few side projects going on, where they're exploring new areas, new environments, etc. If you've never done network programming, try writing some socket code, or play around with remoting, or DirectX. Play around with tools, like a profiler, or measure the performance of different options. Get a book on .NET IL and spend some time under the covers (Richter's book is a good guide here).

    Finally - and this may seem like weird advice from a C# guy - spend some time writing some code in a language such as Perl. Scripting languages lead to a different mindset that can be useful in language.

  • Eric Gunnerson's Compendium

    Signs of the times...

    • 4 Comments
    A great link from Brad
  • 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

    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.

     

Page 1 of 2 (39 items) 12