Reputation: 4037
I need a List of items with sharable behavior.
Example:
Person class
has List<PhoneNumber>
where only one PhoneNumber
is bool IsPrimary
same for other items
has List<EmailAddress>
has List<Address>
Imagine each item (PhoneNumber
, EmailAddress
, Address
) share the same interface ICanBePrimary
which contains the requirement of one property bool IsPrimary
and when in a List<ICanBePrimary>
only one item in the list can have a true value for IsPrimary
.
Upvotes: 1
Views: 124
Reputation: 733
Do you use or could use INotifyPropertyChanged in your Person, EmailAddress, and Address classes?
Do you really require IsPrimary property to be part of your classes?
IF YOU DO
Then you could be listening to all PropertyChanged events(which are part of that interface) on your items and intercept changes to IsPrimary, then you would check if it's switching to ON and then switch IsPrimary on all other items to OFF.
Keep in mind that it is the proper way of achieving behavior you asked for. SO YES it is proper answer.
PS. You could also use CollectionView class if you are only interested in "CurrentItem" behavior.
Upvotes: 0
Reputation: 56457
You can create your own specialized collection class that has the notion of its primary item.
Something like this:
public class ListWithPrimary<T> : List<T> {
public bool HasPrimary { get; private set; }
private T primary;
public T Primary
{
get
{
return primary;
}
set
{
if (!Contains(value)) throw new Exception();
primary = value;
}
}
public void AddPrimary(T item)
{
Add(item);
primary = item;
HasPrimary = true;
}
public void ClearPrimary() {
primary = default(T);
HasPrimary = false;
}
....
}
(Note that the above is still incomplete. You'll have to maintain the invariant that the primary item is always part of the list.)
Upvotes: 2
Reputation: 726479
The cleanest approach would be to hide a list behind a class that lets you enumerate over the content, and provides additional methods for identifying the primary item:
class AddressList : List<Address> {
private int indexOfPrimaryAddress = 0;
public Address PrimaryAddress {
get {
return this[indexOfPrimaryAddress];
}
set {
indexOfPrimaryAddress = this.IndexOf(value);
}
}
// Override more methods to make sure that the index does not become "hanging"
}
An even cleaner implementation would encapsulate the list inside your AddressList
class, and expose only the methods that you want exposed:
class AddressList : IList<Address> {
private int indexOfPrimaryAddress = 0;
private readonly IList<Address> actualList = new List<Address>();
// Implement the List<Address> by forwarding calls to actualList
}
Upvotes: 3