gpt4 book ai didi

c# - 将委托(delegate)引用传递给另一个类,以便一个订阅者可以收听多个发布者?

转载 作者:行者123 更新时间:2023-11-30 23:05:04 24 4
gpt4 key购买 nike

我正在研究事件/委托(delegate)系统的更复杂用途,并且有一个我找不到解决方案的用例。

假设我有两个类,它们都处理从同一基类继承的对象:

public class VegetableStore {
List<VegType> vegtypes;
}
public class MeatStore {
List<MeatType> meatTypes;
}
// MeatType and VegType both extend abstract class FoodType

在一个单独的类中,无论何时将新的 VegType 添加到 VegetableStore,或将新的 MeatType 添加到 MeatStore,我都想监听。

现在,“简单”的方法似乎就是这样:

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) {}
}

然后在我的监听器类中...

vegStore.VegTypeAdded += OnFoodTypeAdded;
meatStore.MeatTypeAdded += OnFoodTypeAdded;

void OnFoodTypeAdded(FoodType foodType, bool added) {}

这感觉比想象的要困惑得多。

我想做的是拥有某种“父”委托(delegate),例如 FoodTypeAddedEventHandler(object source, EventArgs e)然后能够自动订阅任何订阅此事件的事件,订阅来自 Meat 和 Veg 的事件,这样我就可以包含一个中间事件管理器类

public event FoodTypeAddedEventHandler FoodTypeAdded
{
add
{
vegStore.VegTypeAdded += value;
meatStore.MeatTypeAdded += value;
{
remove
{
vegStore.VegTypeAdded -= value;
meatStore.MeatTypeAdded -= value;
}
}

问题是。 vegStore 和 meatStore 没有 FoodTypeAddedHandler 类型的委托(delegate),因此这会导致类型错误。

有没有实用的方法来解决这个问题?似乎无法找到一个合理直接的解决方案来解决这个问题,但我觉得必须有一个。或者,我应该亲吻它吗?

最佳答案

您可以像这样使用通用委托(delegate):

delegate void FoodTypeAddedEventHandler<in T>(T meatType, bool added) where T : FoodType;

然后你有 VegTypeAddedEventHandler 而不是 FoodTypeAddedEventHandler<VegType> 而不是 MeatTypeAddedEventHandler 你有 FoodTypeAddedEventHandler<MeatType> 。最后,你得到的不是 FoodTypeAddedEventHandler ,而是 FoodTypeAddedEventHandler<FoodType> 。修改后,您的“组合”事件处理程序将编译正常:

public event FoodTypeAddedEventHandler<FoodType> FoodTypeAdded
{
add
{
vegStore.VegTypeAdded += value;
meatStore.MeatTypeAdded += value;
{
remove
{
vegStore.VegTypeAdded -= value;
meatStore.MeatTypeAdded -= value;
}
}

或者 - 只需删除所有委托(delegate)类型并使用 Action<FoodType, bool>Action<VegType, bool>Action<MeetType, bool> 。那么您的代码也可以正常编译。

这是可行的,因为两个自定义委托(delegate)都有其第一个类型参数( T )逆变( in 修饰符)。这允许它接受派生类型的参数(因此,委托(delegate) FoodTypeAddedEventHandler<FoodType> 可以接受第一个参数不完全是 FoodType 而是任何派生类型(例如 VegType )的签名。同样适用于 Action 因为在 Action 中所有类型参数也是逆变的(声明带有 in 修饰符)。有关委托(delegate)方差的更多信息,您可以在 documentation 中阅读。

关于c# - 将委托(delegate)引用传递给另一个类,以便一个订阅者可以收听多个发布者?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48972086/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com