如何声明类的 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# 的新手,所以我处于初学者水平,所以对它的工作原理感到非常困惑。请告知
对于 .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 的评论