// VS 2015
定义一个Book类:
namespace ConsoleTest
{
    public class Book
    {
        private string _bookIsbn;
        private string _bookName;  
        private string _press;     
        private string _author;
        private short _edition;
        public string BookIsbn { get { return _bookIsbn; } set { _bookIsbn = value; } }
        public string BookName {get { return _bookName;} set { _bookName = value; } }
        public string Press { get { return _press;} set { _press = value; } }
        public string Author { get {return _author;} set { _author = value; } }
        public short Edition { get {return _edition;} set { _edition = value; } }
    }
}
类似于java的getter和setter方法, C#使用了属性来进行字段的封装。
C#允许在属性内的操作:
- 还可以在get和set内进行各种操作,比如判断输入是否合法等。
 - 可以声明某一个get或者set的访问性比属性的访问性更严格,不能全部都比属性严格(C#2)
 - 可以实现自动属性。(C#3)
 
修改如下:
namespace ConsoleTest
{
    public class Book
    {
        private string _bookIsbn;
        public string BookIsbn { get { return _bookIsbn; } private set { _bookIsbn = value; } }
        public string BookName { get; private set; }
        public string Press { get; set; }
        public string Author { get; set; }
        public short Edition { get; set; }
    }
}
在这个版本代码中,省略了字段保留了属性,并且BookName,Press,Author,Edition均实现了自动属性。C#编译器会自动的将其扩展为和之前的代码一样。
如果查看一下IL代码:(部分)
.class public auto ansi beforefieldinit 
  ConsoleTest.Book
    extends [mscorlib]System.Object
{
  .field private string _bookIsbn
  .field private string '<BookName>k__BackingField'
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() 
    = (01 00 00 00 )
  .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) 
    = (01 00 00 00 00 00 00 00 ) // ........
    // int32(0) // 0x00000000
  .field private string '<Press>k__BackingField'
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() 
    = (01 00 00 00 )
  .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) 
    = (01 00 00 00 00 00 00 00 ) // ........
    // int32(0) // 0x00000000
  .field private string '<Author>k__BackingField'
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() 
    = (01 00 00 00 )
  .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) 
    = (01 00 00 00 00 00 00 00 ) // ........
    // int32(0) // 0x00000000
  .field private int16 '<Edition>k__BackingField'
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() 
    = (01 00 00 00 )
  .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) 
    = (01 00 00 00 00 00 00 00 ) // ........
    // int32(0) // 0x00000000
  .method public hidebysig specialname instance string 
    get_BookIsbn() cil managed 
  {
    .maxstack 1
    .locals init (
      [0] string V_0
    )
    // [7 38 - 7 39]
    IL_0000: nop          
    // [7 40 - 7 57]
    IL_0001: ldarg.0      // this
    IL_0002: ldfld        string ConsoleTest.Book::_bookIsbn
    IL_0007: stloc.0      // V_0
    IL_0008: br.s         IL_000a
    // [7 58 - 7 59]
    IL_000a: ldloc.0      // V_0
    IL_000b: ret          
  } // end of method Book::get_BookIsbn
  .method private hidebysig specialname instance void 
    set_BookIsbn(
      string 'value'
    ) cil managed 
  {
    .maxstack 8
    // [7 72 - 7 73]
    IL_0000: nop          
    // [7 74 - 7 92]
    IL_0001: ldarg.0      // this
    IL_0002: ldarg.1      // 'value'
    IL_0003: stfld        string ConsoleTest.Book::_bookIsbn
    // [7 93 - 7 94]
    IL_0008: ret          
  } // end of method Book::set_BookIsbn
可以看到,BookName和Press等属性扩展出了字段,而BookISBN属性被写成了两种方法:
public hidebysig specialname instance string 
    get_BookIsbn()
以及 private hidebysig specialname instance void 
    set_BookIsbn(
      string 'value'
    )
public string BookIsbn {  private get { return _bookIsbn; } private set { _bookIsbn = value; } }
如果将BookIsbn改为如上形式,编译器会报错,因为get和set都比属性具有更严格访问性。此时的属性其实无用,因为无法从外部进行任何的访问。
public string BookIsbn {  protected get { return _bookIsbn; } private set { _bookIsbn = value; } }
同样,如上的形式也会报错。
如果不对get或者set的访问性进行指定,那么会和属性的访问性一样。但C#禁止对get和set显示声明与属性一样的访问性。下列形式都会报错:
public string Press {  public get; set; }
public string Press {  get; public set; }
public string Press {  public get; public set; }
                    
                
                
            
        
浙公网安备 33010602011771号