Reputation: 15101
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}
}
};
}
Why can it be assigned while it is a readonly property?
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
};
}
Upvotes: 1
Views: 224
Reputation: 37000
A collection-initializer just fills the collection by calling its Add
-method. It does not create it. Thus the following
Children = { ... }
is just syntactic sugar for this:
Children.Add(...);
Children.Add(...);
Children.Add(...);
...
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();
}
As WhateverCollectionType
implements IEnumerable
and has an Add
-method, you may use a collection-initializer.
Just an asside: Actually it´s bit different, the StackLayout
derives from Layout
which initializes the field to some ElementCollection
, which implements IEnumerable
.
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
Upvotes: 6
Reputation: 244
In the example from the documentation there is no new instance of List<Label>
created and assigned to the Children
property. The following code just calls the method Add()
on the existing instance.
Children =
{
new Label{Text="Start",HorizontalOptions=LayoutOptions.Start}
}
basically it just calls
sl.Children.Add(new Label{Text="Start",HorizontalOptions=LayoutOptions.Start});
This on the other hand would also fail cause it would assign a new instance to the Children
property:
Children = new List<Label>
{
new Label{Text="Start",HorizontalOptions=LayoutOptions.Start}
}
Upvotes: 0
Reputation: 394
Because in first case you are constructing it(creating), not assigning. In second case you are trying to modify it
Upvotes: 1