这种模式有哪些缺点来强制实现不变性?

时间:2016-03-31 20:34:49

标签: c# immutability static-classes

鉴于以下课程:

public static class ComboModel
{
    public static Dictionary<int, int[]> Items()
    {
        return new Dictionary<int, int[]>
        {
            {
                1, 
                new[] { 
                    2,
                    3,
                    4  
                }
            }
        };
    }
}

我想确保课堂上数据的不变性,但这感觉javascript-y并且引起了我同行的一些模糊(但强烈)的批评。这有什么问题?

1 个答案:

答案 0 :(得分:4)

只需使用ReadOnlyDictionary,并只分配一次:

public static class ComboModel {
    private static readonly ReadOnlyDictionary<int, int[]> _items = new ReadOnlyDictionary<int, int[]>(new Dictionary<int, int[]> {
        {
            1,
            new[] {
                2,
                3,
                4
            }
        }
    });

    public static IReadOnlyDictionary<int, int[]> Items
    {
        get { return _items; }
    }
}

请注意,您不仅可以像其他人已经提到的那样在每个呼叫上分配新实例 - 您还可以向调用者提供错误的感觉,即他可以修改该字典。在ReadOnlyDictionary中,没有可以修改它的方法。 当调用者知道收到的结构无法更改时,还有其他好处:例如,他可以使用多个线程安全地处理那里的项目。

更新:当然,只读集合不会神奇地将对象存储在该集合中 - 只是集合本身。如果你想在你的例子中确保int []数组的不变性,那么只需将它们只读:

public static class ComboModel {
    private static readonly IReadOnlyDictionary<int, ReadOnlyCollection<int>> _items = new ReadOnlyDictionary<int, ReadOnlyCollection<int>>(new Dictionary<int, ReadOnlyCollection<int>> {
        {
            1,
            Array.AsReadOnly(new[] {
                2,
                3,
                4
            })
        }
    });

    public static IReadOnlyDictionary<int, ReadOnlyCollection<int>> Items
    {
        get { return _items; }
    }
}