为什么我不能将项目强制转换为泛型类型 — 其中泛型类型是一个接口,并在检查该项是否实现了所述接口之后?



说明

我正在尝试为我的游戏编写效果(增益/减益)。以下是我想要构建的内容:

EffectsManager包含所有活动效果。像HealthController这样的类会查询它以获取与健康相关的效果,即实现IHealthEffect接口的效果,并返回仅包含此类效果的列表。

尝试的解决方案

内部EffectsManager

public List<T> GetEffects<T>() {
List<T> effects = new List<T>();
foreach (ActiveEffect activeEffect in activeEffects) {
// ActiveEffect is just a wrapper for Effect that houses duration, time elapsed, etc.
// I only need to return the Effect itself, which houses the logic.
Effect effect = activeEffect.GetEffect();
if (effect is T) {
effects.Add((T)effect);
}
}
return effects;
}

然后,调用方脚本将写入:

List<IHealthEffect> healthEffects = effectsManager.GetEffects<IHealthEffect>();

问题

无法将类型"效果"转换为"T">

effects.Add((T)effect);.

类似问题

无法将类型"Int"隐式转换为"T">

但就我而言,我不是在做隐式的,而是在做明确的转换。为什么编译器不让我继续,我应该使用Convert.ChangeType()- 正如那里建议的那样 - 无论如何?

更多信息

Effect只是一个只有 1 个成员的抽象类:public int priority;

由于效果可能会影响多个属性,例如生命值法力值,因此我决定使用要求实现者编写特定方法的接口,例如:void Execute(HealthController healthController);

你来了:

if (effect is T typed) {
effects.Add(typed);
}

至于为什么:你需要在中间投object(T)(object)effect

但就我而言,我不是在做隐式的,而是在做显式的强制转换。

EffectT是不相关的,因此编译器将尝试转换而不是强制转换,并且显然也没有在类型之间定义转换,因此会出现错误。

正如 Marc 所建议的,您可以充分利用模式匹配:

if (effect is T t) {
effects.Add(t);
}

但是,如果您的代码与发布的内容完全相同,则可以完全通过 LINQ 实现此目的:

var healthEffects = activeEffects.Select(x => x.GetEffect()).OfType<IHealthEffect>();

最新更新