// 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; }

 

posted on 2017-01-16 11:26  DevinSuMi  阅读(273)  评论(0编辑  收藏  举报