首页 > 解决方案 > C# 没有用于覆盖特定类型的可访问扩展方法

问题描述

如果这已经被问过了,请原谅我。我搜索了它,但找不到任何东西。

似乎编译器被这段代码弄糊涂了

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

标签: c#unity3dgenerics

解决方案


当您说void Run<C2>(C2 c)C2泛型类型时,它不是具体类型C2。为了更清楚,请更改C2T

public override void Run<T>(T c)
{
    c.c1Prop = 1; //Is recognized
    c.c2Prop = 2; //Is NOT recognized and is an error
}

您可以访问的原因是层次结构中较早c1Prop的类型约束。where T : C1

解决这个问题的一种方法是使其P1自身通用:

public abstract class P1<T> where T : C1
{
    public abstract void Run(T c);
}

P2看起来像这样:

public class P2 : P1<C2>
{
    public override void Run(C2 c)
    {
        c.c1Prop = 1;
        c.c2Prop = 2;
    }
}

推荐阅读