У меня есть класс Учителя, который имеет свойство
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, так как он будет иметь более одного значения. Я создаю checkListbox в форме Windows, но я не знаю, как получить и установить свойство.
Я думаю, что он должен быть доступен только для чтения, поскольку у меня уже есть значения для списка, например, для Art, Law и т.д., Или может быть, я ошибаюсь, поскольку список будет создан в соответствии с отмеченным списком.
Я новичок в С#, поэтому я нахожусь на уровне новичка, поэтому очень смущен тем, как он будет работать. пожалуйста, порекомендуйте
Для.NET 3.5
Даже если у вас есть свойство readonly типа List, его можно изменить извне объекта, потому что это ссылочный тип. Для лучшей инкапсуляции используйте IEnumerable, если вам не нужен индекс и счетчик. Такой объект не может быть изменен извне класса, кроме элементов, их можно изменить, даже если он IEnumerable. IEnumerable может быть взломан, возвращаясь к списку, а затем изменен.
public IEnumerable<string> SubjectTaught { get; }
Или вы можете использовать ReadOnlyCollection. Это предоставит вам свойство count + indexer, которое не включено в IEnumerable. Все изменения ReadOnlyCollection относятся к обертке не к исходной коллекции, это означает, что инкапсуляция идет далеко.
private List<string> _subjectTaught;
public ReadOnlyCollection<string> SubjectTaught
{
get{ _subjectTaught.AsReadOnly();}
}
Для.NET 4.5
В NET Framework 4.5 вы можете использовать IReadOnlyCollection, который реализуется List и ReadOnlyCollection. Использование AsReadOnly + IReadOnlyCollection не позволяет вызывающему абоненту модифицировать IReadOnlyCollection после кастования IReadOnlyCollection обратно в List, потому что все изменения внесены в обертку AsReadOnly, а не в саму коллекцию.
private List<string> _subjectTaught;
public IReadOnlyCollection<string> SubjectTaught
{
get{ _subjectTaught.AsReadOnly();}
}
Возвращение только IReadOnlyCollection, поскольку интерфейс List не предоставляет оболочку readonly и, таким образом, позволяет взломать, возвращая свойство в 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");
}
}
ПРИМЕЧАНИЯ: Благодаря комментарию Скотта Чемберлена о IReadOnlyCollection в.NET 4.5