views:

1253

answers:

4

Let's assume this class in C#:

public class LimitedList<T> : List<T>
{
    private int _maxitems = 500;

    public void Add(T value) /* Adding a new Value to the buffer */
    {
        base.Add(value);
        TrimData(); /* Delete old data if lenght too long */
    }

    private void TrimData()
    {
        int num = Math.Max(0, base.Count - _maxitems);
        base.RemoveRange(0, num);
    }
}

The compiler gives me this warning in the line "public void Add(T value)":

warning CS0108: 'System.LimitedList.Add(T)' hides inherited member 'System.Collections.Generic.List.Add(T)'. Use the new keyword if hiding was intended.

What do I have to do to avoid this warning?

Thx 4 your help

+10  A: 

You can avoid this warning by adding "new" to the declaration.

public new void Add(T value) { 
 ...
}

However I think you may be approaching this problem a bit wrong by using Inheritance. From my perspective LimitedList is not a List because it expresses very different behavior as it puts a hard constraint on the amount of data in the List. I think it would be much better to not inherit from List but have a List as a member variable.

Another reason why this is a bad idea is that you won't be able to satisfy your class's contract when it is viewed as a List. The following code will use the List`s Add method and not LimitedList.

List<int> list = new LimitedList<int>(10);
for ( i = 0; i < 10000; i++ ) {
  list.Add(i);
}
JaredPar
+1... 14 sec
Mehrdad Afshari
IMO it is wrong, though; it doesn't provide polymorphism...
Marc Gravell
This is not correct you want to override not new.
Dan Blair
@Marc completely agree this is wrong. I added an example of where this is broken.
JaredPar
@Dan agreed, this is why inheritance is bad here.
JaredPar
+1, agreeing that it would be much better to encapsulate a List<T> instance instead of inheriting from it.
Brian Ensink
+9  A: 

No - don't use new here; that doesn't give you polymorphism. List<T> isn't intended for inheritance in this way; use Collection<T> and override the Add InsertItem method.

public class LimitedCollection<T> : Collection<T>
{
    private int _maxitems = 500;

    protected override void InsertItem(int index, T item)
    {
        base.InsertItem(index, item);
        TrimData(); /* Delete old data if lenght too long */
    }

    private void TrimData()
    {
        int num = Math.Max(0, base.Count - _maxitems);
        while (num > 0)
        {
            base.RemoveAt(0);
            num--;
        }
    }
}
Marc Gravell
This is a much better explanation on how to properly code this. Thanks Marc
Jason Heine
than i have to implement the whole interface ?!
No - see update
Marc Gravell
@Bigbohne, yes. You would have to forward all of the calls into your class
JaredPar
@JaredPar - not if you inherit from Collection<T> (which does all that forwarding for you to the base IList<T>)
Marc Gravell
@Marc, I think that even inheriting from Collection is wrong because it's violating an implicit controct. I would expect anything I add to a Collection<T> via Add to be available until I 1) lose control of the object or 2) explicitly remove it. LimitedCollection would violate this contract
JaredPar
@JaredPar - hmmm... indeed, I can't argue with that; I guess it depends what the OP is trying to achieve. But it certainly beats `new` ;-p
Marc Gravell
@Marc, agreed it's better than new because it's at least provides a consistent experience no matter what reference type is used to view the object. IMHO, I think the best approach is to wrap List<T>, implement IEnumerable<T> and pretty much nothing else. There doesn't seem to be any collection style interface other than IEnumerable<T> where LimitedList would not violate an implicit contract.
JaredPar
@all, I just want to Plot realtime data. A "normal" list is fine but growing until "infinity". If you guys know better aproache for this. pls tell me.
TBH I'd just create a new generic class called LimitedList<of T> with an associated interface and be happy :p
Dan
It sounds like you actually want a ring buffer for your numbers. http://en.wikipedia.org/wiki/Circular_buffer
dss539
a ring buffer is something different. although this would also look cool :)
A: 

You need to declare your 'Add' method as a 'new' (replacement) method. Try this:

public class LimitedList<T> : List<T>
{
    private int _maxitems = 500;

    public new void Add(T value) /* Adding a new Value to the buffer */
    {
        base.Add(value);
        TrimData(); /* Delete old data if length too long */
    }

    private void TrimData()
    {
        int num = Math.Max(0, base.Count - _maxitems);
        base.RemoveRange(0, num);
    }
}

notice the 'new' keyword in the 'Add(...' declaration.

Although, in this instance, you should create your own generic class implementing the IList interface. Hope that helps.

Dan
See the other replies about polymorphism to see why this isn't a good idea.
Marc Gravell
A: 

Like others have stated, you need to add the new keyword. The reason for this is because in the base class (List<T>) the Add method hasn't been marked with the keyword "virtual" which basically means "overridable". Therefore, it should be marked as "new".

BFree