原谅我是否已被问到。我搜索了它,但找不到任何东西。
似乎编译器对此代码感到困惑
public abstract class C1
{
public int c1Prop;
}
public class C2 : C1
{
public int c2Prop;
}
public abstract class P1
{
public abstract void Run<T>(T c) where T : C1;
}
public class P2 : P1
{
public override void Run<C2>(C2 c)
{
c.c1Prop = 1; //Is recognized
c.c2Prop = 2; //Is NOT recognized and is an error
}
}
我不明白为什么这在功能级别上不起作用。由于C2扩展了C1,因此它不会违反where检查,但是在重写方法中仍无法识别C2类型。
在某些背景下,我在Unity ScriptableObject中使用了类似的模式,该模式不适用于泛型类,因此无法将泛型类型上移到类级别。虽然将它移到那里确实可以解决问题。
我想出的另一种可能的解决方法是一起摆脱通用方法,而支持转换。但是,这似乎不像泛型那样具有表现力。同样在整个Run方法中的多个地方强制转换c也会很烦人。
答案 0 :(得分:0)
您的方法签名指出该方法应该是通用的,并且不能仅对某些具体类型覆盖它,您可以执行以下操作:
public class P2 : P1
{
public override void Run<T>(T c)
{
c.c1Prop = 1; //Is recognized since you have where T : C1 clause
var c2 = c as C2;
if (c2 != null)
{
c2.c2Prop = 2;
}
}
}
答案 1 :(得分:0)
虽然我支持@DavidG的方法,但是如果您不想在类上使用泛型声明,则可以使用此方法
public interface IC1
{
int prop1 { get; set; }
}
public interface IC2
{
int prop2 { get; set; }
}
public abstract class C1 : IC1
{
#region Implementation of IC1
public int prop1 { get; set; }
#endregion
}
public class C2 : C1, IC2
{
#region Implementation of IC2
public int prop2 { get; set; }
#endregion
}
public abstract class P1
{
public abstract void Run<T>(T c) where T : IC1, IC2;
}
public class P2 : P1
{
public override void Run<T>(T c)
{
c.prop1 = 1;
c.prop2 = 2;
}
}