簡體   English   中英

為什么我們可以使用集合初始值設定項分配只讀IList集合?

[英]Why can we assign readonly IList collection with collection initializer?

StackLayoutreadonly Children屬性的類型為IList<View> 我驚訝地得知,可以為Children分配集合初始值設定項,如以下代碼片段所示(受Xamarin.Forms文檔給出的示例的啟發):

public MainPage()
{   
    StackLayout sl = new StackLayout
    {
        Children =
        {
            new Label{Text="Start",HorizontalOptions=LayoutOptions.Start}
        }
    };
}

為什么當它是只讀屬性時才能分配它?

接下來,我做了一個反例如下。 在這里,編譯器抱怨Children是一個只讀屬性。 這是可以理解的,但前一個不是。 你能告訴我為什么嗎?

public MainPage()
{                       
    IList<Label> labels = new List<Label>
    {
        new Label{Text="Start",HorizontalOptions=LayoutOptions.Start}
    };

    StackLayout sl = new StackLayout
    {
        Children = labels
    };
}

集合初始化器只是通過調用其Add方法來填充集合。 它不會創建它。 因此以下

Children = { ... }

只是語法糖:

Children.Add(...);
Children.Add(...);    
Children.Add(...);
...

您將看到這是假設已經存在一個可以調用Add的集合,否則您將獲得NullReferenceException. 因此, StackLayou的代碼可能與此類似:

class StackLayout 
{
    public readonly WhataverCollectionType Children = new WhateverCollectionType();
}

由於WhateverCollectionType實現IEnumerable並具有Add方法,因此您可以使用collection-initializer。

StackLayout :實際上有點不同, StackLayout派生自Layout ,該Layout將字段初始化為一些實現IEnumerable ElementCollection

您的第二個示例清楚地將列表重新分配給Children ,僅在readonly字段中不允許該列表。 您也可以編寫此代碼,這使它更容易理解:

StackLayout sl = new StackLayout
{
    Children = new List<Label> { ... }
};

編譯成類似於以下內容:

StackLayout sl = new StackLayout(); // will also assign Children to a new list
var list = new List<Label>();
list.Add(...);
list.Add(...);
...
sl.Children = list; // this re-assigns the member which is not allowed as it is readonly

因為在第一種情況下,您正在構造(創建)它,而不是分配。 在第二種情況下,您正在嘗試對其進行修改

在文檔的示例中,沒有創建List<Label>並將其分配給Children屬性的新實例。 以下代碼僅在現有實例上調用方法Add()

 Children =
 {
    new Label{Text="Start",HorizontalOptions=LayoutOptions.Start}
 }

基本上它只是調用

sl.Children.Add(new Label{Text="Start",HorizontalOptions=LayoutOptions.Start});

另一方面,這也會失敗,因為它將為Children屬性分配一個新實例:

 Children = new List<Label>
 {
    new Label{Text="Start",HorizontalOptions=LayoutOptions.Start}
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM