使用泛型类型扩展集合



我的目标是扩展集合对象以支持在从集合中添加、更新或删除项目时进行标记。MSDN 文章提供了针对特定类型进行扩展的示例(示例 2)。我想让它保持通用,这样我就不必为我拥有的每个集合设置一个新类。

这是我到目前为止所拥有的:

public class ChangedEventArgs<T> : EventArgs
{
    public readonly T ChangedItem;
    public readonly T ReplacedWith;
    public readonly ChangeType ChangeType;
    public ChangedEventArgs(ChangeType change, T item, T replacement)
    {
        ChangeType = change;
        ChangedItem = item;
        ReplacedWith = replacement;
    }
}
public enum ChangeType
{
    Added,
    Removed,
    Replaced,
    Cleared
};
class CollectionChangeTracked<T> : Collection<T>
{
    public event EventHandler<ChangedEventArgs<T>> Changed;
    protected override void InsertItem<TParam>(int index, TParam newItem)
    {
        base.InsertItem(index, newItem);
        EventHandler<ChangedEventArgs<T>> temp = Changed;
        if (temp != null)
        {
            temp(this, new ChangedEventArgs<T>(ChangeType.Added, newItem, null));
        }
    }
    protected override void SetItem<TParam>(int index, TParam newItem)
    {
        string replaced = Items[index];
        base.SetItem(index, newItem);
        EventHandler<ChangedEventArgs<T>> temp = Changed;
        if (temp != null)
        {
            temp(this, new ChangedEventArgs(ChangeType.Replaced, replaced, newItem));
        }
    }
    protected override void RemoveItem<TParam>(int index)
    {
        TParam removedItem = Items[index];
        base.RemoveItem(index);
        EventHandler<ChangedEventArgs<T>> temp = Changed;
        if (temp != null)
        {
            temp(this, new ChangedEventArgs<T>(ChangeType.Removed, removedItem, null));
        }
    }
    protected override void ClearItems()
    {
        base.ClearItems();
        EventHandler<ChangedEventArgs<T>> temp = Changed;
        if (temp != null)
        {
            temp(this, new ChangedEventArgs(ChangeType.Cleared, null, null));
        }
    }
}

问题:我在以下行收到错误:基本。InsertItem(index, newItem)它说我有无效的论点,但仅此而已。在 SetItem 和 RemoveItem 中存在相同的问题。

更新了编译代码:

public class ChangedEventArgs<T> : EventArgs
{
    public readonly T ChangedItem;
    public readonly T? ReplacedWith;
    public readonly ChangeType ChangeType;
    public ChangedEventArgs(ChangeType change, T item, T? replacement)
    {
        ChangeType = change;
        ChangedItem = item;
        ReplacedWith = replacement;
    }
}
public enum ChangeType
{
    Added,
    Removed,
    Replaced,
    Cleared
};
class CollectionChangeTracked<T> : Collection<T>
{
    public event EventHandler<ChangedEventArgs<T>> Changed;
    protected override void InsertItem(int index, T newItem)
    {
        base.InsertItem(index, newItem);
        EventHandler<ChangedEventArgs<T>> temp = Changed;
        if (temp != null)
            temp(this, new ChangedEventArgs<T>(ChangeType.Added, newItem, default(T)));
    }

    protected override void SetItem(int index, T newItem)
    {
        T replaced = Items[index];
        base.SetItem(index, newItem);
        EventHandler<ChangedEventArgs<T>> temp = Changed;
        if (temp != null)
            temp(this, new ChangedEventArgs<T>(ChangeType.Replaced, replaced, newItem));
    }
    protected override void RemoveItem(int index)
    {
        T removedItem = Items[index];
        base.RemoveItem(index);
        EventHandler<ChangedEventArgs<T>> temp = Changed;
        if (temp != null)
            temp(this, new ChangedEventArgs<T>(ChangeType.Removed, removedItem, null));
    }
    protected override void ClearItems()
    {
        base.ClearItems();
        EventHandler<ChangedEventArgs<T>> temp = Changed;
        if (temp != null)
            temp(this, new ChangedEventArgs<T>(ChangeType.Cleared, null, null));
    }

@daveL完全正确,你想要的是一个通用事件参数:

public class ChangedEventArgs<T> : EventArgs
{
    public readonly T ChangedItem;
    public readonly T ReplacedWith;
    public readonly ChangeType ChangeType;
    public ChangedEventArgs(ChangeType change, T item, T replacement)
    {
        ChangeType = change;
        ChangedItem = item;
        ReplacedWith = replacement;
    }
}

但是他在回答中遗漏了如何使用它;首先让你的事件处理程序使用与主类相同的类型T

class CollectionChangeTracked<T> : Collection<T>
{
    public event EventHandler<ChangedEventArgs<T>> Changed;
   ....
}

然后,您的各个方法,而不是将类型重新定义为TParam,应该使用在类级别定义的T

protected override void InsertItem(int index, T newItem)
{
    base.InsertItem(index, newItem);
    EventHandler<ChangedEventArgs<T>> temp = Changed;
    if (temp != null)
    {
      // Added <T> after ChangedEventArgs  
      temp(this, new ChangedEventArgs<T>(ChangeType.Added, newItem, default(T)));
    }
}

现场示例:http://rextester.com/XFCLN26271

我想

这会有所帮助,但我有点猜测,因为您的问题含糊且未完成

 public class ChangedEventArgs<T> : EventArgs
    {
        public readonly T ChangedItem;
        public readonly T ReplacedWith;
        public readonly ChangeType ChangeType;
        public ChangedEventArgs(ChangeType change, T item, T replacement)
        {
            ChangeType = change;
            ChangedItem = item;
            ReplacedWith = replacement;
        }
    }

您必须将 ChangedEventArgs 类定义为泛型。

试试这个:

public class ChangedEventArgs<T> : EventArgs
{
    public readonly T ChangedItem;
    public readonly ChangeType ChangeType;
    public readonly T ReplacedWith;
    public ChangedEventArgs(ChangeType change, T item,
        T replacement)
    {
        ChangeType = change;
        ChangedItem = item;
        ReplacedWith = replacement;
    }
}
public enum ChangeType
{
    Added,
    Removed,
    Replaced,
    Cleared
};
class CollectionChangeTracked<T> : Collection<T> 
{
    public event EventHandler<ChangedEventArgs<T>> Changed;
    protected override void InsertItem(int index, T newItem)
    {
        base.InsertItem(index, newItem);
        EventHandler<ChangedEventArgs<T>> temp = Changed;
        if (temp != null)
        {
            temp(this, new ChangedEventArgs<T>(
                ChangeType.Added, newItem, default(T)));
        }
    }
    protected override void SetItem(int index, T newItem)
    {
        T replaced = Items[index];
        base.SetItem(index, newItem);
        EventHandler<ChangedEventArgs<T>> temp = Changed;
        if (temp != null)
        {
            temp(this, new ChangedEventArgs<T>(
                ChangeType.Replaced, replaced, newItem));
        }
    }
    protected override void RemoveItem(int index)
    {
        T removedItem = Items[index];
        base.RemoveItem(index);
        EventHandler<ChangedEventArgs<T>> temp = Changed;
        if (temp != null)
        {
            temp(this, new ChangedEventArgs<T>(
                ChangeType.Removed, removedItem, default(T)));
        }
    }
    protected override void ClearItems()
    {
        base.ClearItems();
        EventHandler<ChangedEventArgs<T>> temp = Changed;
        if (temp != null)
        {
            temp(this, new ChangedEventArgs<T>(
                ChangeType.Cleared, default(T), default(T)));
        }
    }
}

最新更新