I've been reading that inheritance is usually bad code design. Despite that, I'll sometimes inherit from a List or a BindingList of a business object. Here's a simple business object I might use:
public class RowType
{
public string Name { get; set; }
public double Sales { get; set; }
}
Here are two options for an object that holds a collection of RowType
s:
//Option A: "Has-A" relationship
public class RowHolderType
{
private readonly BindingList<RowType> _rows;
public BindingList<RowType> Rows { get { return this._rows; } }
public RowHolderType() { this._rows = new BindingList<RowType>(); }
}
//Option B: "Is-A" relationship
public class RowHolderType : BindingList<RowType>
{
public RowHolderType() : base() { }
public RowHolderType(IList<RowType> list) : base(list) { }
}
I usually go with Option B. I find that I usually have to write less code when I go with Option B. I normally use a class like this for displaying a list of editable data in a WPF window.
Is there some hidden drawback to using Option B? Or can I go on happily extending BindingList<T>
s?
EDIT: Adding an example.
I mentioned in a comment that I might use Option B at times when I want better control over the notifications that BindingList
can send. I might want to indicate that I'm starting a batch of updates, and then later finishing the same batch of updates. To do that, I would inherit BindingList and add some functionality:
public class RowTypeHolder : BindingList<RowType>
{
public event BeforeListChangedEventHandler BeforeListChanged;
public delegate void BeforeListChangedEventHandler(RowTypeHolder sender, RowTypeHolderEventArgs e);
public event AfterListChangedEventHandler AfterListChanged;
public delegate void AfterListChangedEventHandler(RowTypeHolder sender, RowTypeHolderEventArgs e);
public void OnBeforeListChanged(RowTypeHolderEventArgs.ChangeType change, string eventName)
{
if (this.BeforeListChanged != null)
this.BeforeListChanged(this, new RowTypeHolderEventArgs(change, 0, eventName));
}
public void OnAfterListChanged(RowTypeHolderEventArgs.ChangeType change, int numChanges, string eventName)
{
if (this.AfterListChanged != null)
this.AfterListChanged(this, new RowTypeHolderEventArgs(change, numChanges, eventName));
}
}
The caller is responsible for sending the BeforeListChanged
and AfterListChanged
notifications. I haven't tried this with a "Has-A" type relationship, but I assume that that code would be uglier. (Note that I left out the definitions for RowTypeHolderEventArgs
and RowTypeHolderEventArgs.ChangeType
. I don't think it's important for this example.)
Without more context, it's hard for me to decide which one I prefer more, I normally like to structure the code after my mental model of the problem.
Ask yourself the question:
IS RowHolderType
a BindingList<RowType>
in the rhetorical sense? If it is, than yes, inheritance is 100% appropriate.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.