2013-04-03 43 views
3

可以告訴我,爲什麼它會編譯?分配到初始化程序列表中的只讀屬性

namespace ManagedConsoleSketchbook 
{ 
    public interface IMyInterface 
    { 
     int IntfProp 
     { 
      get; 
      set; 
     } 
    } 

    public class MyClass 
    { 
     private IMyInterface field = null; 

     public IMyInterface Property 
     { 
      get 
      { 
       return field; 
      } 
     } 
    } 

    public class Program 
    { 
     public static void Method(MyClass @class) 
     { 
      Console.WriteLine(@class.Property.IntfProp.ToString()); 
     } 

     public static void Main(string[] args) 
     { 
      // ************ 
      // *** Here *** 
      // ************ 

      // Assignment to read-only property? wth? 

      Method(new MyClass { Property = { IntfProp = 5 }}); 
     } 
    } 
} 

回答

8

這是一個嵌套對象初始化程序。它在C#4規範中描述這樣的:

甲成員的初始值,指定一個對象初始化之後等號是嵌套對象初始化 - 也就是說,嵌入對象的初始化。不是將新值賦給字段或屬性,而是將嵌套對象初始值設定項中的賦值作爲賦值給字段或屬性的成員。嵌套對象初始值設定項不能應用於具有值類型的屬性,也不能應用於具有值類型的只讀字段。

所以這個代碼:

MyClass foo = new MyClass { Property = { IntfProp = 5 }}; 

將相當於:

MyClass tmp = new MyClass(); 

// Call the *getter* of Property, but the *setter* of IntfProp 
tmp.Property.IntfProp = 5; 

MyClass foo = tmp; 
+0

好的,現在很清楚。儘管如此,這是一個混亂的語法。 – Spook

2

因爲你正在使用它使用的ItfProp二傳手初始化,Property的制定者。

所以它會在運行時拋出NullReferenceException,因爲Property仍然是null

+0

你能詳細點嗎?標準如何涵蓋這種情況? – Spook

+0

等一下,引導視覺工作室,發佈一些說明示例 – bas

+2

啊,喬恩在家裏,我無法與他競爭:@ – bas

0

因爲

int IntfProp { 
    get; 
    set; 
} 

是不是隻讀。

你沒有調用MyClass.Property的setter,只是getter。