Joe 的个人资料Joe Mayo日志列表 工具 帮助
7月29日

Implicit Backing Stores in C# v3.5

C# v3.5 has a new feature formally called "Auto-Implemented" properties.  I like to call them implicit backing stores.  Having been a big fan of properties for a long time, this a feature I really like.  How many times have you created a property that simply wraps a backing-store field?  For me it is continuous and something I prefer to do because of the encapsulation benefits and the fact that I can go back later and modify the code without any drawbacks.  In a team environment, you also always have the issue of people who code to the backing-store field, rather than the property, then when you change the implementation of the property, you also have to chase down all the field access code or you end up with bugs.  With Implicit Backing Stores, this problem goes away and you still have the flexibility of changing the property implementation later.  Here's an example:
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PropertyTest
{
    class Person
    {
        public string Name { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Person pers = new Person();
            pers.Name = "Joe";
            Console.WriteLine("Hello, " + pers.Name);
        }
    }
}
Notice that in the Person class, the Name property is declared without bodies for get and set accessors.  Regardless, the code in Main works perfectly, printing out "Hello, Joe".
 
If you are wondering where the backing field went or where the string literal "Joe" is being saved, this is more help the C# compiler is giving you.  The backing field still exists, but the C# compiler created it behind the scenes.  Here's the IL generated by the C# compiler for the get accessor:
 
.method public hidebysig specialname instance string
        get_Name() cil managed
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
  // Code size       11 (0xb)
  .maxstack  1
  .locals init (string V_0)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      string PropertyTest.Person::'<Name>k__BackingField'
  IL_0006:  stloc.0
  IL_0007:  br.s       IL_0009
  IL_0009:  ldloc.0
  IL_000a:  ret
} // end of method Person::get_Name
Notice how the CLR is loading a field named '<Name>k__BackingField'.  This is really the backing store field holding "Joe".  Unlike previous versions of C# where a plausible name was used for IL generated code as in get_Name and set_Name, you can't accidentally create a private filed of the backing store name because of the '<Name>' prefix, which isn't allowed in C# identifiers.  Here's the backing store field implementation:
 
.field private string '<Name>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
Here's the implementation of the set accessor:
 
.method public hidebysig specialname instance void
        set_Name(string 'value') cil managed
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
  // Code size       8 (0x8)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  stfld      string PropertyTest.Person::'<Name>k__BackingField'
  IL_0007:  ret
} // end of method Person::set_Name
 
Again, simply saving the result to the backing store field, '<Name>k__BackingField'.
7月28日

VS2008 Multi-Targeting

VS2008 Beta 2 has multi-targeting support, where you can select the .NET Framework you want to build with.  I think it is a good idea.  The first time I recall hearing about this type of feature was when Borland added it to JBuilder 2.0, which allowed you to switch versions of Java.  There were some initial bugs, but it was a neat feature because you could build a Java program written for any version.
 
VS2008 Beta 2 multi-targeting support allows you to build for the .NET Framework v2.0, v3.0, and v3.5.  Sure, it allows me to build an existing .NET Framework v2.0 project.  However, I decided to look at it the other way and say "What if I started out my project in VS2008 Beta 2 as a .NET Framework v2.0 project?"  I found out that it allowed me to compile and run a program with C# v3.5 syntax.
 
I know that C# is a language and multi-targeting is focused on the .NET Framework.  However, do you think it is logical to be able to add C# v3.5 syntax to a project you want to run with a v2.0 CLR?
 
Here's a bug I submitted.  Some people may have a reason why this behavior would or wouldn't be appropriate.  What do you think?