簡體   English   中英

C#-在引用類型上使用私有setter和公共getter

[英]C# - Using a private setter with a public getter on reference types

考慮以下帶有公共獲取器和私有設置器的簡短代碼示例:

public class Foo        
{
    public class Bar
    {
        ...
    }

    public Bar fooBar { get; private set; }
    public int valueType { get; private set; }
}

我想確保只能從Foo類內部將類成員寫入。 這適用於上面示例中的值類型(如valueType 但是像嵌套類fooBar這樣的引用類型如何表現呢?

我可以使用公共獲取者返回的引用來操縱我的私有成員嗎?

如果您要引用的類型是可變的,那么可以,任何引用了“容器”的人都可以獲取引用,然后對對象進行突變。 例如:

using System;
using System.Collections.Generic;

class Container
{
    public List<string> List { get; private set; }
        = new List<string>();
}

class Program
{
    static void Main()
    {
        var container = new Container();
        var list = container.List;
        Console.WriteLine(list.Count); //0

        container.List.Add("foo");
        Console.WriteLine(list.Count); // 1        
    }
}

在這里, List<string>Container之外被突變。 一種避免這種情況的選擇是對可變數據使用只讀視圖:

using System;
using System.Collections.Generic;

class Container
{
    private readonly List<string> list = new List<string>();

    public IReadOnlyList<string> ListView { get; }

    public Container()
    {
        ListView = list.AsReadOnly();
    }

    public void AddItem(string item)
    {
        list.Add(item);
    }
}

class Program
{
    static void Main()
    {
        var container = new Container();
        Console.WriteLine(container.ListView.Count); //0

        // container.ListView.Add("foo"); // Compile-time error

        container.AddItem("foo");
        Console.WriteLine(container.ListView.Count); // 1        
    }
}

請注意,即使編譯時類型為IReadOnlyList<T> ,您也不應該直接從屬性中直接返回列表,因為那樣的話,調用者可以直接將其轉換回List<T>並對其進行突變。 List<T>.AsReadOnly()在列表周圍返回一個真正的只讀包裝對象,因此調用者實際上無法對其進行突變。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM