C# 将委托引用传递给另一个类,以便一个订阅者可以侦听多个发布者?
我正在研究事件/委托系统更复杂的用途,有一个我找不到解决方案的用例 假设我有两个类,它们都处理从同一基类继承的对象:C# 将委托引用传递给另一个类,以便一个订阅者可以侦听多个发布者?,c#,events,delegates,C#,Events,Delegates,我正在研究事件/委托系统更复杂的用途,有一个我找不到解决方案的用例 假设我有两个类,它们都处理从同一基类继承的对象: public class VegetableStore { List<VegType> vegtypes; } public class MeatStore { List<MeatType> meatTypes; } // MeatType and VegType both extend abstract class FoodType 这
public class VegetableStore {
List<VegType> vegtypes;
}
public class MeatStore {
List<MeatType> meatTypes;
}
// MeatType and VegType both extend abstract class FoodType
这感觉比可能的要混乱得多
我想做的是使用某种“父”委托,例如FoodTypeAddedEventHandler(objectsource,EventArgs e)
然后能够自动订阅订阅此事件的任何事件,订阅来自Meat和Veg的事件,这样中间eventmanager类就可以包含
public event FoodTypeAddedEventHandler FoodTypeAdded
{
add
{
vegStore.VegTypeAdded += value;
meatStore.MeatTypeAdded += value;
{
remove
{
vegStore.VegTypeAdded -= value;
meatStore.MeatTypeAdded -= value;
}
}
问题是。vegStore和meatStore没有FoodTypeAddHandler类型的委托,因此这会导致类型错误
有没有切实可行的办法?似乎找不到一个合理的直截了当的方法来解决这个问题,但我觉得肯定有一个。或者,我应该亲吻它吗?您可以像这样使用通用委托:
public class VegetableStore {
List<VegType> vegtypes;
public delegate void VegTypeAddedEventHandler(VegType vegType, bool added);
public event VegTypeAddedEventHandler VegTypeAdded;
//...
protected virtual void OnVegTypeAdded(VegType vegType, bool added) {}
}
public class MeatStore {
List<MeatType> meatTypes
public delegate void MeatTypeAddedEventHandler(MeatType meatType, bool added);
public event MeatTypeAddedEventHandler MeatTypeAdded;
//...
protected virtual void OnMeatTypeAdded(MeatType meatType, bool added) {}
}
delegate void FoodTypeAddedEventHandler<in T>(T meatType, bool added) where T : FoodType;
或者-只需删除所有代理类型并使用操作
、操作
和操作
。然后,您的代码也可以很好地编译
这是因为两个自定义委托都有其第一个类型参数(
T
)逆变(修改器中的)。这允许它接受派生类型的参数(因此,委托FoodTypeAddedEventHandler
可以接受签名,其中第一个参数不完全是FoodType
,而是任何派生类型(例如VegType
)。这同样适用于操作
,因为在操作
中,所有类型参数也是逆变的(在
修饰符中用声明)。有关代理差异的更多信息,您可以阅读。首先,我要删除您的特定代理类型-它们不会比仅使用具有完全相同签名的EventHandler
给您带来任何好处。当您改为使用EventHandler
时,问题应该会消失(无论如何,我怀疑——这只是通过检查)。我的示例不清楚,因为我确实使用了自定义参数-将进行整理。你是对的,EventHandler将以其他方式解决无法正常工作的问题,因为vegStore.VegTypeAdded
将与FoodTypeAddedEventHandler
@jonsket为什么?我尝试过了,它编译得很好(虽然没有试着跑).Note我说过要更改所有委托类型,包括vegStore.VegTypeAdded。@JonSkeet可能您没有注意到VegType和MeatType都继承自同一个类FooType?这在操作代码中没有显示,但在该代码的注释中提到了。但这不允许您订阅事件-您需要在另一个方向上使用通用变量。Pu是这样的吗:如果事件是用MeatType
值引发的,您希望vegStore.VegTypeAdded
处理程序如何接受该值?@JonSkeet我不希望这样,但我不明白这是怎么可能的。FoodTypeAdded
事件不可开票,您只能订阅\取消订阅它(OP不需要调用它,只需订阅即可)。仅VegTypeAdded
(类型FoodTypeAddedEventHandler
)和MeatTypeAdded
(类型FoodTypeAddedEventHandler
)可以调用。我不知道如何使用委托订阅VegTypeAdded,其中第一个参数是给定代码的MeatType
。您可以使用VegType
或FoodType
(通过FoodTypeAdded
伪事件)进行订阅。
delegate void FoodTypeAddedEventHandler<in T>(T meatType, bool added) where T : FoodType;
public event FoodTypeAddedEventHandler<FoodType> FoodTypeAdded
{
add
{
vegStore.VegTypeAdded += value;
meatStore.MeatTypeAdded += value;
{
remove
{
vegStore.VegTypeAdded -= value;
meatStore.MeatTypeAdded -= value;
}
}