将通用列表 <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)));
}
}
我编写了一个事件,该事件应该将具有类型 (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)));
}
}