Как объявить get и установить методы доступа к свойству List класса

1

У меня есть класс Учителя, который имеет свойство

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 и т.д., Или может быть, я ошибаюсь, поскольку список будет создан в соответствии с отмеченным списком.

Я новичок в С#, поэтому я нахожусь на уровне новичка, поэтому очень смущен тем, как он будет работать. пожалуйста, порекомендуйте

Теги:
collections
getter

1 ответ

3

Для.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

  • 1
    Для ReadOnlyCollection, если все, что вам нужно, это Count и вы используете .NET 4.5 или новее, вы можете сделать это лучше, вернув интерфейс IReadOnlyCollection, чтобы дать вам дополнительный уровень абстракции. Однако вы теряете несколько вещей, таких как индексатор.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню