Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. How to run custom code when List.Add or List.Remove is running

How to run custom code when List.Add or List.Remove is running

Scheduled Pinned Locked Moved C#
questioncsharpdesigntutorial
4 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Chris Richner
    wrote on last edited by
    #1

    Hi, Before generics I used something like this to connect childs with parent classes

    interface IMyItem
    {
    CollectionOwner Owner{get;set;}
    }
    class MyCollection : System.Collections.CollectionBase
    {
    // ctor
    public MyCollection(CollectionOwner owner)
    {
    _owner = owner;
    }
    // internal interface
    protected override OnAdd(object item)
    {
    if(item is IMyItem) ((IMyItem)item).Owner = _owner;
    }
    }

    this way one was able to add items to a owner class owner.Items.Add(new Item()) and the owner had the item instance in his list while the item had a reference to his owner, which made a call like item.Remove() possible instead of calling owner.Items.Remove(item) Now, .net 2.0 introduced generics, way cool. But how do I implement this behaviour with generics? There is no overrideable method instead of using the brute force method with new

    class MyCollection<T> : List<T>
    where T : IMyItem

    {
    // ctor
    MyCollection(CollectionOwner owner)
    {
    _owner = owner;
    }
    new public void Add(T item)
    {
    item.Owner = _owner;
    base.Add(item);
    }
    }

    this way if one is casting MyCollection back to List<> my custom add method isn't run. bad design how can I extend generic collection base classes with such logic to do some extra work on each add or remove?

    myMsg.BehindDaKeys = "Chris Richner";

    J D C 3 Replies Last reply
    0
    • C Chris Richner

      Hi, Before generics I used something like this to connect childs with parent classes

      interface IMyItem
      {
      CollectionOwner Owner{get;set;}
      }
      class MyCollection : System.Collections.CollectionBase
      {
      // ctor
      public MyCollection(CollectionOwner owner)
      {
      _owner = owner;
      }
      // internal interface
      protected override OnAdd(object item)
      {
      if(item is IMyItem) ((IMyItem)item).Owner = _owner;
      }
      }

      this way one was able to add items to a owner class owner.Items.Add(new Item()) and the owner had the item instance in his list while the item had a reference to his owner, which made a call like item.Remove() possible instead of calling owner.Items.Remove(item) Now, .net 2.0 introduced generics, way cool. But how do I implement this behaviour with generics? There is no overrideable method instead of using the brute force method with new

      class MyCollection<T> : List<T>
      where T : IMyItem

      {
      // ctor
      MyCollection(CollectionOwner owner)
      {
      _owner = owner;
      }
      new public void Add(T item)
      {
      item.Owner = _owner;
      base.Add(item);
      }
      }

      this way if one is casting MyCollection back to List<> my custom add method isn't run. bad design how can I extend generic collection base classes with such logic to do some extra work on each add or remove?

      myMsg.BehindDaKeys = "Chris Richner";

      J Offline
      J Offline
      Judah Gabriel Himango
      wrote on last edited by
      #2

      Rather from inheriting from List<T>, have your class implement IList<T>, and keep a List<T> field in your class. Something like this:

      public class MyCollection<T> : IList<T>
      {
      readonly List<T> list = new List<T>();

      public void Add(T item)
      {
          item.Owner = \_owner;
          list.Add(item);
      }
      
      ....
      

      }

      Of course, for you to set the Owner property of the item, there must be a constraint on your T class type. You could accomplish this like this:

      interface IOwnable
      {
      CollectionOwner Owner { get; set; }
      }

      The tell your MyCollection object that only IOwnable objects can be stored in it.

      class MyCollection<T> : IList<T>
      where T : IOwnable
      {
      ...
      }

      *edit* alternately, as Daniel said, inheriting from the System.Collections.ObjectModel.Collections would require less work. You'll still need the IOwnable constraint if you want to set the owner on the items.

      Tech, life, family, faith: Give me a visit. I'm currently blogging about: God-as-Judge, God-as-Forgiver The apostle Paul, modernly speaking: Epistles of Paul Judah Himango

      1 Reply Last reply
      0
      • C Chris Richner

        Hi, Before generics I used something like this to connect childs with parent classes

        interface IMyItem
        {
        CollectionOwner Owner{get;set;}
        }
        class MyCollection : System.Collections.CollectionBase
        {
        // ctor
        public MyCollection(CollectionOwner owner)
        {
        _owner = owner;
        }
        // internal interface
        protected override OnAdd(object item)
        {
        if(item is IMyItem) ((IMyItem)item).Owner = _owner;
        }
        }

        this way one was able to add items to a owner class owner.Items.Add(new Item()) and the owner had the item instance in his list while the item had a reference to his owner, which made a call like item.Remove() possible instead of calling owner.Items.Remove(item) Now, .net 2.0 introduced generics, way cool. But how do I implement this behaviour with generics? There is no overrideable method instead of using the brute force method with new

        class MyCollection<T> : List<T>
        where T : IMyItem

        {
        // ctor
        MyCollection(CollectionOwner owner)
        {
        _owner = owner;
        }
        new public void Add(T item)
        {
        item.Owner = _owner;
        base.Add(item);
        }
        }

        this way if one is casting MyCollection back to List<> my custom add method isn't run. bad design how can I extend generic collection base classes with such logic to do some extra work on each add or remove?

        myMsg.BehindDaKeys = "Chris Richner";

        D Offline
        D Offline
        Daniel Grunwald
        wrote on last edited by
        #3

        Instead of inheriting from List, inherit from System.Collections.ObjectModel.Collection. There you can override ClearItems, RemoveItem and InsertItem, which will be called by all normal Add/Clear/Insert/Remove/RemoveAt methods.

        1 Reply Last reply
        0
        • C Chris Richner

          Hi, Before generics I used something like this to connect childs with parent classes

          interface IMyItem
          {
          CollectionOwner Owner{get;set;}
          }
          class MyCollection : System.Collections.CollectionBase
          {
          // ctor
          public MyCollection(CollectionOwner owner)
          {
          _owner = owner;
          }
          // internal interface
          protected override OnAdd(object item)
          {
          if(item is IMyItem) ((IMyItem)item).Owner = _owner;
          }
          }

          this way one was able to add items to a owner class owner.Items.Add(new Item()) and the owner had the item instance in his list while the item had a reference to his owner, which made a call like item.Remove() possible instead of calling owner.Items.Remove(item) Now, .net 2.0 introduced generics, way cool. But how do I implement this behaviour with generics? There is no overrideable method instead of using the brute force method with new

          class MyCollection<T> : List<T>
          where T : IMyItem

          {
          // ctor
          MyCollection(CollectionOwner owner)
          {
          _owner = owner;
          }
          new public void Add(T item)
          {
          item.Owner = _owner;
          base.Add(item);
          }
          }

          this way if one is casting MyCollection back to List<> my custom add method isn't run. bad design how can I extend generic collection base classes with such logic to do some extra work on each add or remove?

          myMsg.BehindDaKeys = "Chris Richner";

          C Offline
          C Offline
          Chris Richner
          wrote on last edited by
          #4

          Thanks guys, This way round things look like they did in System.Collections.xx namespace. Seems like I just got the wrong base class ;(

          myMsg.BehindDaKeys = "Chris Richner";

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups