简体   繁体   中英

How to declare get and set accessors of a List property of a class

I have a Teacher class which has a property

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;
        }
    }

I want to create a list for SubjectTaught as it will have more than one value. I am creating a checkedListbox in windows form but I don't know how to get and set the property.

I think it should be read-only as I already have the values for the list for eg Art,Law,etc or may be I am wrong as I the list will be created as per the checked listbox.

I am new to C# so I am at beginner level so very confused as to how it will work. Please advise

For .NET 3.5

Even if you have readonly property of type List, it can be modified from outside of the object, because it is reference type. For better encapsulation use IEnumerable if you don't need indexer and Count. Such object cannot be modified from the outside of the class, except items, these can be modified even it is IEnumerable. IEnumerable can be hacked by casting back to the List and then modified.

public IEnumerable<string> SubjectTaught  { get; }

Or you can use ReadOnlyCollection . This will provide you Count property + indexer, which is not included in IEnumerable. All changes of ReadOnlyCollection apply to the wrapper not to the original collection, it means the encapsulation goes even far.

private List<string> _subjectTaught;

public ReadOnlyCollection<string> SubjectTaught
{ 
   get{ _subjectTaught.AsReadOnly();}
}

For .NET 4.5

In NET Framework 4.5 you can use IReadOnlyCollection which is implemented by List and by ReadOnlyCollection as well. Usage of AsReadOnly + IReadOnlyCollection prevent caller from modifying the IReadOnlyCollection after casting IReadOnlyCollection back to List, because all changes are made to AsReadOnly wrapper, not the collection itself.

private List<string> _subjectTaught;

public IReadOnlyCollection<string> SubjectTaught
{ 
   get{ _subjectTaught.AsReadOnly();}
}

Returning only IReadOnlyCollection as interface of List doesn't provide the readonly wrapper and thus enable a hack by casting the property back to List and modifying the original collection:

private List<string> _subjectTaught;

public IReadOnlyCollection<string> SubjectTaught
{ 
   get{ _subjectTaught;}
}

See comparing IReadOnlyCollection and ReadOnlyCollection .

For better understanding try this example:

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");    
    }
}

NOTES: Thanks to Scott Chamberlain's comment about IReadOnlyCollection in .NET 4.5

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM