[英]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.