Skip to content

Instantly share code, notes, and snippets.

@maacpiash
Last active February 5, 2018 18:56
Show Gist options
  • Save maacpiash/00513880c76a7650f6e98ef17aba0ce9 to your computer and use it in GitHub Desktop.
Save maacpiash/00513880c76a7650f6e98ef17aba0ce9 to your computer and use it in GitHub Desktop.
The problem is that a class property with a private setter can be modified if the property is of reference type.
using System;
using System.Collections.Generic;
namespace DilemmaWithReference
{
class Program
{
static void Main(string[] args)
{
Person p = new Person();
p.Numbers.Add(3); // I don't want this to be possible
Console.WriteLine(p.Numbers.Count.ToString());
}
}
public class Person
{
public List<int> Numbers
{
get { return numbers; }
private set { numbers = value; }
}
private List<int> numbers;
public Person()
{
numbers = new List<int>();
numbers.Add(0); // This is okay
}
}
}
@thehoneymad
Copy link

thehoneymad commented Feb 5, 2018

This is a classic problem.

Ask yourself two things.

  • Do you only need to iterate the collection from outside? Then just cast it to a IEnumerable<int> and expose it.
  • Do you need random access outside? Then go for a ReadOnlyCollection<T>. It is quite strict, dont forget that.

The situation you need to be aware of is :

ICollection<Foo> evil = (ICollection<Foo>) bar.Foos;
evil.Add(...);

You can also yield return to make things simpler. I personally avoid the skip(0) hack.

Suggested reading:

https://stackoverflow.com/questions/491375/readonlycollection-or-ienumerable-for-exposing-member-collections

#FollowTheSkeet

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment