我有一个拥有属性
的Teacher类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#的新手,所以我处于初级水平,所以非常困惑它是如何工作的。请指教
答案 0 :(得分:3)
对于.NET 3.5
即使您具有List类型的只读属性,也可以从对象外部进行修改,因为它是引用类型。如果您不需要索引器和Count,可以更好地encapsulation使用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和IReadOnlyCollection实现的ReadOnlyCollection。使用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;}
}
请参阅comparing IReadOnlyCollection and 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的评论