如何声明类的 List 属性的 get 和设置访问器

本文关键字:get 属性 设置 访问 List 声明 何声明 | 更新日期: 2023-09-27 18:37:06

我有一个具有属性的教师类

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;
        }
    }

我想为主题教学创建一个列表,因为它将具有多个值。我正在Windows窗体中创建一个选中的列表框,但我不知道如何获取和设置该属性。

我认为它应该是只读的,因为我已经有了例如艺术、法律等列表的值,或者可能是我错了,因为我将根据选中的列表框创建列表。

我是 C# 的新手,所以我处于初学者水平,所以对它的工作原理感到非常困惑。请告知

如何声明类的 List 属性的 get 和设置访问器

对于 .NET 3.5

即使您具有 List 类型的只读属性,也可以从对象外部对其进行修改,因为它是引用类型。为了更好地封装,如果不需要索引器和计数,请使用 IEnumerable。这样的对象不能从类的外部修改,除了项目,这些项目也可以修改,即使它是 IEnumerable。IEnumerable 可以通过转换回列表然后修改来破解。

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 转换回列表后修改 IReadOnlyCollection,因为所有更改都是对 AsReadOnly 包装器进行的,而不是集合本身。

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

仅返回 IReadOnlyCollection 作为 List 的接口不提供只读包装器,因此通过将属性强制转换为 List 并修改原始集合来启用黑客攻击:

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 的评论