1

Is there a way to do this:

class BetList : List<Bet>
{
    public uint Sum { get; private set; }
    void Add(Bet bet) : base.Add(bet)  // <-- I mean this
    {
        Sum += bet.Amount;
    } 
}

I want to use the base List class to do the List operation. I'd like to implement the Summming only.

4 Answers4

6

you should use composition, instead of derivation

class BetList
{
     List<Bet> _internalList=new List<Bet>();
     //forward all your related operations to _internalList;
}
David
  • 15,894
  • 22
  • 55
  • 66
  • 3
    Additionally you can implement `IEnumerable` or `IList` if you would like to use the class either of those ways, without having to subclass `List`. – Dave Cousineau Mar 28 '13 at 12:41
  • 3
    Well, 'alternatively' would mean instead of your answer. I mean 'additionally' because it is compatible with your answer. – Dave Cousineau Mar 28 '13 at 12:58
2

If you need to extend an existing collection type you should use Collection<T> which is designed for this purpose. For example:

public class BetList : Collection<Bet>
{
    public uint Sum { get; private set; }

    protected override void ClearItems()
    {
        Sum = 0;
        base.ClearItems();
    }

    protected override void InsertItem(int index, Bet item)
    {
        Sum += item.Amount;
        base.InsertItem(index, item);
    }

    protected override void RemoveItem(int index)
    {
        Sum -= item.Amount;
        base.RemoveItem(index);
    }

    protected override void SetItem(int index, Bet item)
    {
        Sum -= this[i].Amount;
        Sum += item.Amount;
        base.SetItem(index, item);
    }
}

A good explanation of the differences between List<T> and Collection<T> can be found here: What is the difference between List (of T) and Collection(of T)?

The above class would be used like this:

var list = new BetList();
list.Add( bet );  // this will cause InsertItem to be called
Community
  • 1
  • 1
Phil
  • 42,255
  • 9
  • 100
  • 100
0

If you want to keep the class derivation instead of composition, try this:

class BetList : List<Bet>
{
    public uint Sum { get; private set; }
    new void Add(Bet bet) 
    {
        base.Add(bet);
        Sum += bet.Amount;
    } 
}
PrimeNerd
  • 194
  • 4
  • 3
    And then someone passes `BetList` to a method taking `List` and oh look we're of to hell in a hand-basket! There is _(almost)_ **never** a good reason for doing this, and this is not one of those reasons. – Binary Worrier Mar 28 '13 at 12:46
  • @BinaryWorrier to be fair, this is the only answer that directly answers the actual question, (although I'm not sure what the policy is about what to do when someone asks how to do something they probably shouldn't do). – Dave Cousineau Mar 28 '13 at 13:03
  • @BinaryWorrier Can you explain the problem (in more details) with this solution? Since my main post I noticed that List<> has a Sum method but except that I still don't understand why this solution is problematic. – Szabolcs Sipos Mar 28 '13 at 19:07
0

How about calculating the sum on-the-fly when you need it instead of storing it ?

class BetList : List<Bet>
{
    public uint Sum 
    { 
        get { return this.Count > 0 ? this.Sum(bet => bet.Amount) : 0; }
    }
}
Alex
  • 23,004
  • 4
  • 39
  • 73
  • You don't need the explicit check for an empty sequence; [`Sum` will return 0 in that case](http://msdn.microsoft.com/en-gb/library/bb535184.aspx). – anton.burger Mar 28 '13 at 13:16
  • @shambulator That's correct, but I'm a strong fan of absolutely failsafe code no matter what – Alex Mar 29 '13 at 08:04
  • I'll clarify: it's *documented* to return 0 in that case. I don't know what failure your check is guaranteeing against :) – anton.burger Mar 30 '13 at 11:23