我想到了一种访问列表属性的简洁方法:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="192dp"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.ContentFrameLayout
android:id="@+id/contents_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
这种方式即使private List<int> _stages;
public List<int> Stages
{
get
{
return (_stages ?? (_stages = new List<int>())).OrderBy(s => s).ToList();
}
set
{
_stages = value;
}
}
为空,如果我使用Stages
,也会先进行初始化,然后再添加值。但它不起作用,我真的无法弄清楚,因为没有太多的调试。 Stages.Add(1)
已初始化,但无论我拨打_stages
多少次,Stages.Add(1)
仍为空列表。
我错过了什么?
答案 0 :(得分:3)
return (_stages ?? (_stages = new List<int>())).OrderBy(s => s).ToList();
这相当于:
var stages = _stages;
if (stages == null)
stages = _stages = new List<int>();
return stages.OrderBy(s => s).ToList();
因此,当您在列表为空时正确初始化列表时,您仍然总是返回.OrderBy(s => s).ToList()
。
Enumerable.ToList()
来电总是创建一个新列表。
因此getter返回的列表是一个新列表,它没有链接到内部支持的_stages
列表。因此,当您向列表中添加项目时,您将其添加到已排序的副本,而不是原始列表。
您可以通过将排序后的列表一直指定回支持字段来更改此设置,但这仍然会导致在您访问该属性时始终对字段进行排序的开销。一般来说访问getter不应该有副作用,所以我会避免这样做。最好在对象上提供一个清晰的SortStages
方法来实际对列表进行排序。
此外,您应该考虑使用List.Sort()
对列表进行就地排序,这样您就不会得到新的列表对象。
答案 1 :(得分:2)
通过执行ToList()
,您将返回一个新列表。如果您拨打Add
,则不会在_stages