NET问答: 为什么仅有 getter 的属性,还可以在构造函数中赋值 ?
咨詢區
Noam B.:
我建了一個這樣的屬性。
public?int?Foo?{?get;?}?毫無疑問,這是一個只讀屬性,當我在構造函數中無意對它賦值時,我發現居然可以改變它的值???比如下面的代碼。
public?MyClass(string?name) {Foo?=?5; }為什么會這樣?它不是只讀的嗎?
回答區
Yacoub Massad:
首先這是 C#6 引入的新特性,它允許我們創建只讀的屬性,但這里有一個問題,實踐中我們常常需要給這個只讀屬性賦予一個非默認值,比如你這里的 Foo=5 而不是它原生的 Foo=0,所以這是一個設計哲學問題。
如果你想在 構造函數 之外修改屬性的值,這時候 ReadOnly 的限定就會讓其拋出一個編譯時錯誤了。
Rahul Nikate:
自動屬性是在 C# 3.0 中被引入的,它的好處就是幫你省去了人肉 field 的繁瑣,接下來你可以通過 構造函數 初始化自動屬性為一個非 default 值,在 C# 6.0 中又做了進一步簡化,可以直接使用 屬性初始化器 對屬性進行初始化操作,省去了構造函數的繁瑣賦值。
在之前你可能需要這樣做。
public?class?MyClass {public?int?Foo?{?get;?}public?MyClass(int?foo){Foo?=?foo;} }現在你可以使用 屬性初始化器 了。
public?string?Foo?{?get;?}?=?"SomeString";public?List<string>?Genres?{?get;?}?=?new?List<string>?{?"Comedy",?"Drama"?};點評區
其實這種問題,看 IL 代碼是最清楚的。
.class?public?auto?ansi?beforefieldinit?ConsoleApp3.MyClassextends?[mscorlib]System.Object {//?Fields.field?private?initonly?int32?'<Foo>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)//?Methods.method?public?hidebysig?specialname?instance?int32?get_Foo?()?cil?managed?{.custom?instance?void?[mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()?=?(01?00?00?00)//?Method?begins?at?RVA?0x205c//?Code?size?7?(0x7).maxstack?8//?return?<Foo>k__BackingField;IL_0000:?ldarg.0IL_0001:?ldfld?int32?ConsoleApp3.MyClass::'<Foo>k__BackingField'IL_0006:?ret}?//?end?of?method?MyClass::get_Foo.method?public?hidebysig?specialname?rtspecialname?instance?void?.ctor?(int32?foo)?cil?managed?{//?Method?begins?at?RVA?0x2064//?Code?size?16?(0x10).maxstack?8//?{IL_0000:?ldarg.0//?(no?C#?code)IL_0001:?call?instance?void?[mscorlib]System.Object::.ctor()IL_0006:?nop//?Foo?=?foo;IL_0007:?nopIL_0008:?ldarg.0IL_0009:?ldarg.1IL_000a:?stfld?int32?ConsoleApp3.MyClass::'<Foo>k__BackingField'//?}IL_000f:?ret}?//?end?of?method?MyClass::.ctor//?Properties.property?instance?int32?Foo(){.get?instance?int32?ConsoleApp3.MyClass::get_Foo()}}?//?end?of?class?ConsoleApp3.MyClass從上面的 .field private initonly int32 '<Foo>k__BackingField' 可以看出, '<Foo>k__BackingField' 被 readonly 標記了,構造函數中只是對其原始 field 進行賦值,參考如下代碼:
public?class?MyClass{private?readonly?int?<Foo>k__BackingField';public?MyClass(int?foo){<Foo>k__BackingField'?=?foo;}} 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的NET问答: 为什么仅有 getter 的属性,还可以在构造函数中赋值 ?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面向.NET开发人员的Dapr——状态管
- 下一篇: 日志ILog(文件日志/控制台日志/控件