簡體   English   中英

如何聲明get和設置類的List屬性的訪問器

[英]How to declare get and set accessors of a List property of a class

我有一個教師班,有一個屬性

class Teacher:Employee
    {
        //private List<string> SubjectTaughtList = new List<string>();

        public string SubjectTaught { get; set; }

        public string Qualification{ get; set; }

        public Teacher() { }

        public Teacher(string id,string title, string fn,string ln, DateTime dob, 
                       string gender,string houseno,string street,string city,string county,
                       string phone,string workPhone, string email,string workEmail,DateTime doj,
                       string status,decimal sal,List<string> subject,string qualification)
            : base(id, title, fn,ln, dob, gender,houseno,street,city,county, phone, 
                   workPhone, email, workEmail, doj, status, sal)
        {
            SubjectTaught = subject;
            Qualification = qualification;
        }
    }

我想為SubjectTaught創建一個列表,因為它將有多個值。 我在Windows窗體中創建一個checkedListbox但我不知道如何獲取和設置屬性。

我認為它應該是只讀的,因為我已經有了例如Art,Law等列表的值,或者可能是我錯了,因為我將按照選中的列表框創建列表。

我是C#的新手,所以我處於初級水平,所以我很困惑它是如何工作的。 請指教

對於.NET 3.5

即使您具有List類型的只讀屬性,也可以從對象外部進行修改,因為它是引用類型。 為了更好的封裝,如果您不需要索引器和Count,請使用IEnumerable 這樣的對象不能從類的外部修改,除了項目,這些都可以修改,即使它是IEnumerable。 IEnumerable可以通過強制轉換回List然后修改來攻擊。

public IEnumerable<string> SubjectTaught  { get; }

或者您可以使用ReadOnlyCollection 這將為您提供Count屬性+索引器,它不包含在IEnumerable中。 ReadOnlyCollection的所有更改都適用於包裝器而不是原始集合,這意味着封裝甚至可以實現。

private List<string> _subjectTaught;

public ReadOnlyCollection<string> SubjectTaught
{ 
   get{ _subjectTaught.AsReadOnly();}
}

對於.NET 4.5

在.NET Framework 4.5中,您可以使用由List和ReadOnlyCollection實現的IReadOnlyCollection 使用AsReadOnly + IReadOnlyCollection會阻止調用者在將IReadOnlyCollection強制轉換回List之后修改IReadOnlyCollection,因為所有更改都是對AsReadOnly包裝器進行的,而不是對集合本身進行的。

private List<string> _subjectTaught;

public IReadOnlyCollection<string> SubjectTaught
{ 
   get{ _subjectTaught.AsReadOnly();}
}

僅返回IReadOnlyCollection作為List的接口不提供只讀包裝器,從而通過將屬性轉換回List並修改原始集合來啟用hack:

private List<string> _subjectTaught;

public IReadOnlyCollection<string> SubjectTaught
{ 
   get{ _subjectTaught;}
}

請參閱比較IReadOnlyCollection和ReadOnlyCollection

為了更好地理解,請嘗試此示例

public class MyClass
{
    private List<string> _list = new List<string>();

    public MyClass()
    {
        _list.Add("banana");
        _list.Add("orange");
        _list.Add("apple");
    }

    public IReadOnlyCollection<string> ReadOnly
    {
        get { return _list; }
    }

    public IReadOnlyCollection<string> ReadOnlyWithWrapper
    {
        get { return _list.AsReadOnly(); }
    }
}

class Program
{
    static void Main(string[] args)
    {
        MyClass my = new MyClass();

        //modify by hack
        ((List<string>)my.ReadOnly).Add("Cherries");

        Console.WriteLine("no wrapper");

        foreach (var item in my.ReadOnly)
        {
            Console.WriteLine(item); //will include cherries
        }

        Console.WriteLine("with wrapper");


        MyClass my2 = new MyClass();

        //cannot be modify by hack, unless reflection is used
        //throw InvalidCastException
        ((List<string>)my2.ReadOnlyWithWrapper).Add("cherries");    
    }
}

注意:感謝Scott Chamberlain關於.NET 4.5中的IReadOnlyCollection的評論

暫無
暫無

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

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