简体   繁体   中英

Is this an example of a good use of inheritence?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM