I was wrestling with the fact that Calendar.SelectedDates is read-only. I wanted a way to programmatically select multiple dates in a calendar. I found the following snippet of code, which does exactly what I want, but I can't understand why it works:
protected void Page_Load(object sender, EventArgs e)
{
SelectedDatesCollection dates = Calendar1.SelectedDates;
dates.Add(new DateTime(2012, 5, 1));
dates.Add(new DateTime(2012, 5, 5));
dates.Add(new DateTime(2012, 5, 9));
}
What I would EXPECT (given my limited knowledge of C#), is completely the opposite:
protected void Page_Load(object sender, EventArgs e)
{
ArrayList datelist = new ArrayList();
datelist.Add(new DateTime(2012, 5, 1));
datelist.Add(new DateTime(2012, 5, 5));
datelist.Add(new DateTime(2012, 5, 9));
Calendar1.SelectedDates = new SelectedDatesCollection(datelist);
}
HOW is the SelectedDates read-only property affected by a local SelectedDatesCollection variable? Why does adding to that local variable affect the Calendar1.SelectedDates property?
(this is just a drag-n-drop ASP.Net Calendar, with no altered/special properties)
The SelectedDatesCollection as a property is ReadOnly, but you can still change it as an object, as in add or remove items.
There is a difference between changing the object (aka calling it's methods with change it's data), and changing the object reference itself, as a member of a class, etc.
By doing:
SelectedDatesCollection dates = Calendar1.SelectedDates;
You are not COPYING the collection, but just saving it's reference, as in giving it another name.
Ultimately, you could also do:
protected void Page_Load(object sender, EventArgs e)
{
Calendar1.SelectedDates.Add(new DateTime(2012, 5, 1));
Calendar1.SelectedDates.Add(new DateTime(2012, 5, 5));
Calendar1.SelectedDates.Add(new DateTime(2012, 5, 9));
}
It is just that one would say the other way is more readable.
dates
and Calendar1.SelectedDates
contain a reference to the exact same object.
Calling the Add
method on dates
is just like calling it on Calendar1.SelectedDates
, and vice-versa.
The reason you could not reassign Calendar1.SelectedDates
as you try to do in your 2nd piece of code (which does not compile), is that SelectedDates is marked as read-only, as you said.
Marking a member as read-only simply means that it will only be assigned immediately or in the constructor of the class/struct/etc.
It does not, however, mean that you cannot change data within that object.
From now on it's just some extra info
There is an class ReadOnlyCollection, which does not allow to change it's ELEMENTS.
So, having a readonly ReadOnlyCollection, for example, would mean you cannot change the member, and you cannot change the elements as well.
Examples:
public class Class1
{
public List<int> Numbers = new List<int> {1, 2, 3};
}
public class Class2
{
public readonly List<int> Numbers = new List<int> {1, 2, 3};
}
public class Class3
{
public ReadOnlyCollection<int> Numbers = new ReadOnlyCollection<int> {1, 2, 3};
}
public class Class3
{
public readonly ReadOnlyCollection<int> Numbers = new ReadOnlyCollection<int> {1, 2, 3};
}
Differences:
var c1 = new Class1();
var c2 = new Class2();
var c3 = new Class3();
var c4 = new Class4();
c1.Numbers = new List<int> {4, 5, 6}; // Works
c1.Numbers.Clear(); // Works
c2.Numbers = new List<int> {4, 5, 6}; // Error
c2.Numbers = c2.Numbers; // Error - you just can't reassign it!
c2.Numbers.Clear(); // Works - you are just calling the Clear method of the existing list object.
c3.Numbers = new ReadOnlyCollection<int> {4, 5, 6}; // Works - the member is not readonly
// ReadOnlyCollection doesn't allow to change it's elements after initializing it.
// It doesn't even have these functions:
c3.Numbers.Clear(); // Error
c3.Numbers.Add(); // Error
c3.Numbers.Remove(2); // Error
c4.Numbers = new ReadOnlyCollection<int> {4, 5, 6}; // Error - the member is marked as readonly
// ReadOnlyCollection doesn't allow to change it's elements after initializing it.
// It doesn't even have these functions:
c4.Numbers.Clear(); // Error
c4.Numbers.Add(); // Error
c4.Numbers.Remove(2); // Error