繁体   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