简体   繁体   中英

Inheriting a List<> in c# and overriding the constructor

I'm trying to create a wrapper around List to do some specific things I want, such as compute max min, extract specific values from some elements, etc.

I start with

    public struct datum {
      public UInt32[] chan;
      public UInt64 sample_number;
      public UInt32 time;
      public UInt32 source_sector;
    } 

    public class dataSet : List<datum> {
     bool dirty=true;
     ....
    }

the methods are typically like this (I want to know if the list has been modified as I have a max()/min() function that only parses the data when it has been modified and caches the values to reuse if the List has not been modified)

     public new void Add(datum x ) {
        base.Add(x);
        this.dirty = true;
    }

However, I'm not sure how to create a constructor. This syntax does not work.. how can I get this type of behavior?

    public dataSet(int count) {
        this = (dataSet) new List<datum>(count);
    }

I also have this constructor, which seems to work fine (no compilation errors) though untested

    public dataSet(List<datum> data) {
        this.AddRange(data);
    }

I came across a post that said that you should use a Collection and a List is used for speed. Though I need the speed, and I'm not sure why a Collection would be better?

--UPDATE--

I don't want to use linq as you can't create something that computes max/min simultaneously as efficiently as this:

    public void recalculateMaxMin() {
        foreach (var d in data) {
            for (int i = 0; i < 16; i++) {
                if (d.chan[i] > max[i]) max[i] = d.chan[i];
                if (d.chan[i] < min[i]) min[i] = d.chan[i];
            }
        }
    }

Thnx

I'm trying to create a wrapper around List to do some specific things I want, such as compute max min, extract specific values from some elements, etc.

Don't. Just use LINQ to Objects. That's what it was designed for:

var list = new List<int> { 10, 20, 30 };
var average = list.Average();
var max = list.Max();
// etc

In general, I would advise against deriving from List<T> anyway - that's not what it was designed for. However, if you must, you just chain from one constructor to a base constructor:

public dataSet(int count) : base(count)
{
    // Add in any extra code you want to here. Probably none in this case.
    // It would execute *after* the base constructor call.
}

See my article on constructors for more information about constructor chaining.

(I'd also strongly advise you to change the name - dataSet doesn't comply with .NET naming conventions, and DataSet would mean something else entirely to most .NET developers.)

You can never ever set "this" to something in C#. I think you are looking for this:

public dataSet(int count)
     : base(count)
{ }

However in my opinion you should take a look at "System.Linq" namespace. I think what you are trying to implement has been done before by Microsoft. 'Select', 'Join', 'Where' and many other clauses has been already implemented in Linq. Also you can use "INotifyCollectionChanged" interface to implement the dirty thing.

Here are some references:

  1. INotifyCollectionChanged
  2. Linq

If you realy need to implement a complete List class with a new behavior, implementing "System.Collections.Generic.IList" interface is the only thing that will rock your idea in an advanced and perfect way. It's more customizable than inheriting from the List class and trying to change everything you have no access to.

Hope it helps

Cheers

public dataSet(int count) 
    : base(count)  {
}

You can call the base type's constructor using base()

public dataSet(int count) : base(count) 
{  
    // no need to implement anything here. base(count) will call the base
    // type's constructor
}

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