具有支持属性的列表没有添加值

时间:2016-09-05 10:25:52

标签: c# list

我想到了一种访问列表属性的简洁方法:

<?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)仍为空列表。

我错过了什么?

2 个答案:

答案 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

中结束