将通用列表 <T> 作为委托参数传递

Passing a generic List<T> as a delegate parameter

我编写了一个事件,该事件应该将具有类型 (T) 的通用项目的列表传递给所有订阅者:

public delegate void GenericListItemCountChangedEvent(List<Object> sender, GenericListItemCountChangedEventArgs e);
public event GenericListItemCountChangedEvent GenericListItemCountChanged;

private void RaiseGenericListItemCountChanged<T>(List<T> List) where T : BaseElem {
    if (GenericListItemCountChanged != null)
        GenericListItemCountChanged(List as List<Object>, new GenericListItemCountChangedEventArgs(typeof(T)));
}

这是来自 class 的声明,它订阅了上面的事件:

 _catalog.GenericListItemCountChanged += (sender, e) => GenericListItemCountChanged(sender, e);

这是将事件转发到订阅者内部的方法:

private void GenericListItemCountChanged(List<Object> sender, Catalog.GenericListItemCountChangedEventArgs e) {
    Catalog.ListTypes changedListType = Catalog.GetListTypeFromList(changedList); 
    //GetListTypeFromList expects parameter to be a type of <T> where T : BaseElem
}

显然,List<Object> 不能转换为 List<T> where T : BaseElem

如果你能提供一个解决方案,在处理事件的方法中检索带有“真实”类型项目的列表,我会接受你的回答。
(恢复原始列表状态)

列表中项目的“真实”类型存储在 EventArgs 中。
但是不知道能不能帮到我...

解决方案:
如果没有@ChrFin 的帮助,我无法解决这个问题,谢谢伙伴!

公共class目录:对象

public delegate void GenericListItemCountChangedEvent(IEnumerable<BaseElem> sender, GenericListItemCountChangedEventArgs e);
public event GenericListItemCountChangedEvent GenericListItemCountChanged;

private void RaiseGenericListItemCountChangedEvent<T>(List<T> List) where T : BaseElem {
    if (GenericListItemCountChanged != null) {
        GenericListItemCountChanged(List, new GenericListItemCountChangedEventArgs());
    }
}
public void ForceRaiseGenericListItemCountChangedEvent<T>(List<T> List) where T : BaseElem {
    RaiseGenericListItemCountChangedEvent(List);
}

public class GenericListItemCountChangedEventArgs {
    public GenericListItemCountChangedEventArgs() {
    }
}
    public static ListTypes GetListTypeFromList<T>(IEnumerable<T> List) where T : BaseElem {
        Type typeofT = List.GetType().GetGenericArguments()[0];
        //typeofT now contains correct subtype of 'BaseElem'
        return ListTypes.SomeType //based on 'typeOfT'
    }

公共部分class MainWindow : Window

    _catalog.GenericListItemCountChanged += (sender, e) => GenericListItemCountChanged(sender, e);
private void GenericListItemCountChanged(IEnumerable<BaseElem> sender, Catalog.GenericListItemCountChangedEventArgs e) {
            Catalog.ListTypes changedListType = Catalog.GetListTypeFromList(sender);
            //We now know the changed ListType
}

非常感谢!

有两(三)种方法可以解决这个问题:Covariance 和泛型:

1) 泛型:
您还需要创建一个通用委托:

public class YourClass<T> where T : BaseElem
{
    public delegate void GenericListItemCountChangedEvent<T>(List<T> sender,
                             GenericListItemCountChangedEventArgs e);
    public event GenericListItemCountChangedEvent<T> GenericListItemCountChanged;

    private void RaiseGenericListItemCountChanged<T>(List<T> List)
    {
        if (GenericListItemCountChanged != null)
        {
            GenericListItemCountChanged(List,
               new GenericListItemCountChangedEventArgs(typeof(T)));
        }
    }
}

当然,在这种情况下,您只能使用一种基类型的显式类型BaseElem

2) 协方差:
使用 IEnumerable<T> 接口而不是显式类型来支持协变:

public delegate void GenericListItemCountChangedEvent(IEnumerable<BaseElem> sender,
                         GenericListItemCountChangedEventArgs e);
public event GenericListItemCountChangedEvent GenericListItemCountChanged;

private void RaiseGenericListItemCountChanged(IEnumerable<BaseElem> List)
{
    if (GenericListItemCountChanged != null)
    {
        var itemType = List.Count() > 0 ? List.First().GetType() : typeof(BaseElem);
        GenericListItemCountChanged(List,
            new GenericListItemCountChangedEventArgs(itemType));
    }
}

3) 丑陋,但可以工作:铸造:

public delegate void GenericListItemCountChangedEvent(List<BaseElem> sender,
                         GenericListItemCountChangedEventArgs e);
public event GenericListItemCountChangedEvent GenericListItemCountChanged;

private void RaiseGenericListItemCountChanged<T>(List<T> List) where T : BaseElem
{
    if (GenericListItemCountChanged != null)
    {
        GenericListItemCountChanged(List.Cast<BaseElem>().ToList(),
            new GenericListItemCountChangedEventArgs(typeof(T)));
    }
}