Reputation: 910
I have classes like this,
class Base
{
int Id { get; set; }
}
class Derived1 : Base
{
string DerivedProperty1 { get; set; }
}
class Derived2 : Base
{
string DerivedProperty2 { get; set; }
}
Now I have a collection class like this
public class MyCollection
{
List<Base> items;
public void Add(Base baseItem)
{
// if baseItem is Derived1, if items contain an item of type Derived1 and has the same DerivedProperty1 value as baseItem, throw exception
// if baseItem is Derived2, if items contain an item of type Derived2 and has the same DerivedProperty2 value as baseItem, throw exception
items.Add(baseItem);
}
}
I don't think that checking type of baseItem then casting is a very good practice, is it? Otherwise how do you suggest I solve this design problem?
Upvotes: 0
Views: 309
Reputation: 82504
You can't access derived class properties from base class without casting to the derived class first. However, in your case, you can do something different - instead of your current Add
method, that takes a Base
instance as a parameter, create a couple of Add
method overloads, one for each derived class:
public void Add(Derived1 item)
{
if(items.OfType<Derived1>().Any(i => i.DerivedProperty1 == item.DerivedProperty1)
throw new InvalidOperationException("An item with the same DerivedProperty1 already exist");
items.Add(baseItem);
}
public void Add(Derived2 item)
{
if(items.OfType<Derived2>().Any(i => i.DerivedProperty2 == item.DerivedProperty2)
throw new InvalidOperationException("An item with the same DerivedProperty2 already exist");
items.Add(baseItem);
}
Upvotes: 1
Reputation: 174369
Based on your code and comments, the correct approach would be to give Base
a IsDuplicateOf
method and override this in the derived classes. Something like this:
class Base
{
int Id { get; set; }
public virtual bool IsDuplicateOf(Base other)
{
return other != null && Id == other.Id;
}
}
class Derived1 : Base
{
string DerivedProperty1 { get; set; }
public override bool IsDuplicateOf(Base other)
{
return IsDuplicateOf(other as Derived1);
}
private bool IsDuplicateOf(Derived1 other)
{
return other != null && DerivedProperty1 == other.DerivedProperty1;
}
}
class Derived2 : Base
{
string DerivedProperty2 { get; set; }
public override bool IsDuplicateOf(Base other)
{
return IsDuplicateOf(other as Derived2);
}
private bool IsDuplicateOf(Derived2 other)
{
return other != null && DerivedProperty2 == other.DerivedProperty2;
}
}
And you would use that method in your Add
method:
public void Add(Base baseItem)
{
if(items.Any(x => baseItem.IsDuplicateOf(x)))
throw new DuplicateItemException(...);
items.Add(baseItem);
}
Please note however, that this approach might become slow if there are many items in the list and the code inside IsDuplicateOf
gets more complex.
Upvotes: 1