为什么我们可以使用集合初始值设定项分配只读IList集合? [英] Why can we assign readonly IList collection with collection initializer?
问题描述
StackLayout 的 readonly
Children
属性的类型为 IList< View>
.我很惊讶地知道 Children
可以分配给集合初始值设定项,如以下代码片段所示(受
The readonly
Children
property of StackLayout
is of type IList<View>
. I got surprised knowing Children
can be assigned with collection initializer as shown in the following code snippet (inspired by an example given by Xamarin.Forms documentation):
public MainPage()
{
StackLayout sl = new StackLayout
{
Children =
{
new Label{Text="Start",HorizontalOptions=LayoutOptions.Start}
}
};
}
问题
为什么它是只读属性才能分配?
Question
Why can it be assigned while it is a readonly property?
接下来,我做了一个反例如下.在这里,编译器抱怨 Children
是只读属性.这是可以理解的,但前一个不是.你能告诉我为什么吗?
Next, I made a counter example as follows. Here the compiler complains that Children
is a readonly property. It is understandable but the previous one is not. Could you tell me why?
public MainPage()
{
IList<Label> labels = new List<Label>
{
new Label{Text="Start",HorizontalOptions=LayoutOptions.Start}
};
StackLayout sl = new StackLayout
{
Children = labels
};
}
推荐答案
一个集合初始化器只是通过调用其 Add
方法来填充该集合.它不会创建.因此,以下
A collection-initializer just fills the collection by calling its Add
-method. It does not create it. Thus the following
Children = { ... }
只是语法糖:
Children.Add(...);
Children.Add(...);
Children.Add(...);
...
您会看到这假定已经有一个集合,可以在其上调用 Add
,否则您将得到一个 NullReferenceException.
StackLayou
的代码可能与此类似:
You see this assumes there already is a collection on which you can call Add
, otherwise you´d get a NullReferenceException.
So the code of the StackLayou
is probably similar to this:
class StackLayout
{
public readonly WhataverCollectionType Children = new WhateverCollectionType();
}
随着 WhateverCollectionType
实现 IEnumerable
并具有 Add
方法,您可以使用collection-initializer.
As WhateverCollectionType
implements IEnumerable
and has an Add
-method, you may use a collection-initializer.
顺便提一句:实际上,有些不同, StackLayout
是从 Layout
派生的,它将字段初始化为某些 ElementCollection
,该实现 IEnumerable
.
Just an asside: Actually it´s bit different, the StackLayout
derives from Layout
which initializes the field to some ElementCollection
, which implements IEnumerable
.
您的第二个示例显然将列表重新分配给 Children
,而在 readonly
字段中则不允许使用此列表.您也可以编写此代码,这使它更容易理解:
Your second example clearly reassigns a list to Children
, which is not allowed ony a readonly
-field. You could also write this, which makes this a bit easier to understand:
StackLayout sl = new StackLayout
{
Children = new List<Label> { ... }
};
这被编译为类似于以下内容的东西:
This is compiled to something similar to this:
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
这篇关于为什么我们可以使用集合初始值设定项分配只读IList集合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!