I know the answer (it's 42)

A blog on coding, .NET, .NET Compact Framework and life in general....

September, 2007

Posts
  • I know the answer (it's 42)

    Non-virtual calls to virtual methods

    • 3 Comments

    C# compiler is known to emit virtual calls for non-virtual methods (callvirt instead of call IL instruction, maybe that be the topic of my next post). However, sometimes it's forced to do the exact opposite

    Consider the following code

        class B
        {
            public virtual void Foo()
            {
                Console.WriteLine("Base::Foo");
            }
        }
    
        class D : B
        {
            public override void Foo()
            {
                base.Foo();
                this.Foo(); // this is infinite recursion. Put just for example
                Console.WriteLine("Derived::Foo");
            }
        }

    Here B::Foo is a virtual method and hence should be called virtually for both the calls in D::Foo. However, that's not the case.

    For the above code the emitted IL looks like

        L_0001: ldarg.0 
        L_0002: call instance void BaseCall.B::Foo()
        L_0007: nop 
        L_0008: ldarg.0 
        L_0009: callvirt instance void BaseCall.B::Foo()

    So for base.Foo() call the non-virtual call instruction is generated and for the this.Foo() call the virtual callvirt instruction is generated.

    The reason is obviously simple. If a virtual call was made on base.Foo() then the call would've landed in the derived D::Foo which would again call base.Foo() resulting in infinite recursion.

    Any guess on what happens for the following code

        class B
        {
            public virtual void Foo()
            {
                Console.WriteLine("Base::Foo");
            }
        }
    
        class C : B
        {
            public override void Foo()
            {
                Console.WriteLine("C::Foo");
            }
        }
    
        class D : C
        {
            public override void Foo()
            {
                base.Foo();
                Console.WriteLine("Derived::Foo");
            }
    }
  • I know the answer (it's 42)

    Unions in C#

    • 2 Comments

    Usage of unions in the native world is pretty common. However, the same is not true for the .NET world. However, while using interop sometimes you need to fiddle around this these.

    In C# you go about defining unions using the Explicit layout supported by struct as follows.

    [StructLayout(LayoutKind.Explicit)]
    public struct MyUnion
    {
        [FieldOffset(0)]
        public UInt16 myInt;
    
        [FieldOffset(0)]
        public Byte byte1;
    
        [FieldOffset(1)]
        public Byte byte2;
    }

    Here the StructLayout(LayoutKind.Explicit) is used to indicate that the stuct definition contains the layout explicitely. FieldOffset(offset) is used to specify the offset of the struct field from the start of the struct.

    In the example above the layout of the struct is somewhat as follows

    <<========== MyUnion (16 bits)========>>
    +--------------------------------------+
    |             myInt (16-bit)           |
    +------------------+-------------------+
    |  byte1 (8 bit)   |   byte2 (8 bit)   |
    +------------------+-------------------+

    byte1 and byte2 share storage with myInt. The following code prints them out and highlight the fact that the system I used (Intel processor based) is little-endian.

    MyUnion union;
    union.byte1 = 0; // needed to make the compiler happy
    union.byte2 = 0;
    union.myInt = 0xAABB;
    Console.WriteLine("{0:X}", union.byte1);
    Console.WriteLine("{0:X}", union.byte2);
    
    // output is
    BB
    AA

    Since the system is little-endian the LSB (0xBB) goes to the first byte and the MSB (0xAA)goes to the second.

    <rant>

    All this is very cool. The only thing that made me a bit unhappy is that the definite assignment verifier couldn't figure out that I needn't do the byte1, byte2 assignment to access them.

    </rant>

  • I know the answer (it's 42)

    Maintained by Microsoft

    • 1 Comments

    Saw this on the side of a road in my recent trip to Bangalore.

    1402459597_b62a6c631c

    Sorry for the quality though, I took it from a moving Bike and that too in very bad light.

  • I know the answer (it's 42)

    Cool new C# syntactic sugar

    • 10 Comments

    Just the other day I ranted about all the explicit get; set; implementation and I found this out today.

    I was reviewing some code and I saw something like this

    class MyClass
    {
        public int Property {
            get; set;
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            MyClass mc = new MyClass();
            mc.Property = 42;
            Console.WriteLine(mc.Property);
        }
    }

    I was completely confused. How the hell is there a abstract property in a concrete class? Then I figured out that this is new short-hand supported by Visual Studio 2008 (code-named Orcas and you can check this out in the latest beta).

    The compiler generates the field for the property and also generates the code in the get set to point to the field.

    internal class MyClass
    {
        // Fields
        [CompilerGenerated]
        private int <Property>k__BackingField;
    
        // Properties
        public int Property
        {
            [CompilerGenerated]
            get
            {
                return this.<Property>k__BackingField;
            }
            [CompilerGenerated]
            set
            {
                this.<Property>k__BackingField = value;
            }
        }
    }
  • I know the answer (it's 42)

    Coding conventions

    • 13 Comments

    <rant>

    Most of the coding convention I've seen being used by SW houses seems to promote wastage of lines. I suspect that since in many cases code size is measured in LOC it actually helps quoting a larger number. E.g. I start getting a tad irritated when I have to write code as follows

    // Why do I have to put in the enclosing curly braces :(
    if(flag)
    {
       Func();
    }
    // Can't I just use get { return foo; } and set {foo = value; }
    public CFoo Foo { get { return foo; } set { foo = value; } }
    </rant>
  • I know the answer (it's 42)

    Geek talk - Soul searching

    • 1 Comments

    Capture

Page 1 of 1 (6 items)