Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make IEnumerable<T> readonly?

Why are the lists list1Instance and p in the Main method of the below code pointing to the same collection?

class Person
    {
        public string FirstName = string.Empty;
        public string LastName = string.Empty;

        public Person(string firstName, string lastName) {
            this.FirstName = firstName;
            this.LastName = lastName;
        }
    }

    class List1
    {
        public List<Person> l1 = new List<Person>();

        public List1()
        {
            l1.Add(new Person("f1","l1"));
            l1.Add(new Person("f2", "l2"));
            l1.Add(new Person("f3", "l3"));
            l1.Add(new Person("f4", "l4"));
            l1.Add(new Person("f5", "l5"));
        }
        public IEnumerable<Person> Get()
        {
            foreach (Person p in l1)
            {
                yield return p;
            }

            //return l1.AsReadOnly(); 
        }

    }  

    class Program
    {

        static void Main(string[] args)
        {
            List1 list1Instance = new List1();

            List<Person> p = new List<Person>(list1Instance.Get());           

            UpdatePersons(p);

            bool sameFirstName = (list1Instance.l1[0].FirstName == p[0].FirstName);
        }

        private static void UpdatePersons(List<Person> list)
        {
            list[0].FirstName = "uf1";
        }
    }

Can we change this behavior with out changing the return type of List1.Get()?

Thanks

like image 747
gk. Avatar asked Dec 11 '08 14:12

gk.


1 Answers

In fact, IEnumerable<T> is already readonly. It means you cannot replace any items in the underlying collection with different items. That is, you cannot alter the references to the Person objects that are held in the collection. The type Person is not read only, however, and since it's a reference type (i.e. a class), you can alter its members through the reference.

There are two solutions:

  • Use a struct as the return type (that makes a copy of the value each time it's returned, so the original value will not be altered — which can be costly, by the way)
  • Use read only properties on the Person type to accomplish this task.
like image 102
mmx Avatar answered Oct 12 '22 20:10

mmx