Question

It's a design question. I have a business object, and 5 business object types that are derived from it.

I also will have a class which has BindingList as a member. I will have 5 classes derived from it.

Since covariance doesn't work here, how would you structure the design to minimize code repetition? I could of course chuck the BindingList and go with DataTable in which case the problem is eliminated.

But since everyone raves about BindingList I would LOVE to see how you guys would approach this.

SOLUTION (based on Pavel Minaev's answer):

public class SampleBase
    {
        protected string m_seq;
        protected string m_id;
        protected string m_weight;
        protected string m_units;       

        public SampleBase(string seq, string id, string weight, string units)
        {
            Seq = seq;
            Id = id;
            Weight = weight;
            Units = units;
        }

        public SampleBase() { }

        public string Seq
        {
            get { return m_seq; }
            set { m_seq = value; }
        }

        public string Id
        {
            get { return m_id; }
            set { m_id = value; }
        }

        public string Weight
        {
            get { return m_weight; }
            set { m_weight = value; }
        }

        public string Units
        {
            get { return m_units; }
            set { m_units = value; }
        }

    }

    public class FwdSample : SampleBase
    {
        protected string m_std_id;

        public FwdSample() { }

        public FwdSample (string seq, string id, string weight, string units, string std_id ) : base(seq, id, weight, units)
        {
            StdId = std_id;
        }

        public string StdId 
        {
            get { return m_std_id; }
            set { m_std_id = value; }
        }
    }
    //End of Sample Classes





    public abstract class RunBase<T> where T : SampleBase , new()
    {
        protected BindingList<T> m_samples;



        public RunBase() {}

        public void Add(T sample)
        {
            m_samples.Add(sample);
        }

        public void Update(int index, T sample)
        {
            m_samples[index] = sample;
        }

        public void Delete(int index)
        {
            m_samples.RemoveAt(index);
        }



        public BindingList<T> Samples
        {
            get { return m_samples; }
        }
    }


    public class FwdRun : RunBase<FwdSample>
    {

        public FwdRun()
        {
            m_samples = new BindingList<FwdSample>();
        }


    }
Was it helpful?

Solution

Assuming your BindingList member is private (or protected), and isn't otherwise exposed in your class API, you'd probably want something like this:

  class Base
  {
      // No BindingList here. All members that don't need it should be here
      ...
  }

  class Base<TDerived> : Base where TDerived : Base<TDerived>
  {
       BindingList<TDerived> list = new BindingList<TDerived>();

       // All members that need BindingList should be here
  }

  class Derived1 : Base<Derived1> { ... }
  class Derived2 : Base<Derived2> { ... }
  ...

OTHER TIPS

This example only works with .net 3.5 or higher. :(

Perhaps a property that returns all of the inherited objects. I had a similar question and using System.Linq. Here is what I used:

List<A> testme = new List<B>().OfType<A>().ToList();

Or cast all of them to the parent:

List<A> testme = new List<B>().Cast<A>().ToList();

The above code was from this answer. Thanks Matt.

If you have an inheritance relationship between the children, why not use BindingList<TheBaseClass> as your main collection type?

The most prominent example of when you would need to use covariance is when you wanted to treat a BindingList<TheDerivedClass> as BindingList<TheBaseClass>. Can you give us a specific example of where this is tripping you up? Many of the scenarios for which coviarance is an anaswer can also be solved with a combination of generics, constraints and occasionally additional interfaces.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top