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