C#没有可用的扩展方法来覆盖特定类型

时间:2018-09-13 16:58:31

标签: c# unity3d generics

原谅我是否已被问到。我搜索了它,但找不到任何东西。

似乎编译器对此代码感到困惑

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也会很烦人。

2 个答案:

答案 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; 
    }
}