通用类型约束不适用

Generic type constraint not applying

我正在写一个模拟器,我遇到了一个有趣的错误:

error CS0311: The type 'T' cannot be used as type parameter 'T' in the generic type or method 'Emulator.Emulator<T>'. There is no implicit reference conversion from 'T' to 'Emulator.Emulator<T>.EmulatorState'.

错误出在以下代码(特别是 Emulator.IOpcode 处的 T):

protected abstract class Chip8Opcode<T> : Emulator<T>.IOpcode where T : Chip8.Chip8State

简化代码如下(ideone):

public abstract class Emulator<T> where T : Emulator<T>.EmulatorState
{
    public abstract class EmulatorState { }
    public interface IOpcode
    {
        bool IsValid(T state);
        void Execute(T state);
    }
}

public class Chip8 : Emulator<Chip8.Chip8State>
{
    public class Chip8State : EmulatorState { }
}

abstract class Chip8Opcode<T> : Emulator<T>.IOpcode where T : Chip8.Chip8State
{
}

根据我的理解,T 应该仅限于 Chip8State,它可以转换为 EmulatorState(这是 Emulator<> 所要求的),但是通用类型约束似乎不适用于 TEmulator<T> 中,因为错误是 "The type 'T'" 而不是 "The type 'Chip8State'." 这是编译中的错误还是有更好的方法将类型约束应用于继承的泛型?

注意:这不是关于类型冲突的类似问题的重复,因为 T 从未被视为受约束的类型。

另外:如果以后需要的话,泛型已经到位,可以轻松扩展模拟器,尽管如果知道是否有更好的方法会很高兴。

你就不能这样说吗:

abstract class Chip8Opcode<T> : Emulator<Chip8.Chip8State>.IOpcode
    where T : Chip8.Chip8State

此外,检查关于 "covariance and contravariance in generics" 的主题。在某种程度上,只有 C# 中的接口才有可能。

我使用的另一种解决问题的方法是为每个 class 创建一个接口并让它们实现它,这允许在以后的 class 中正确应用协变和逆变。

interface IEmulator<out T> where T : IEmulatorState
{ ... }
public interface IEmulatorState
{ ... }

允许:

public abstract class Emulator<T> : IEmulator<T> where T : IEmulatorState
{ ... }

public interface IOpcode<in T> where T : IEmulatorState
{ ... }

最重要的是

abstract partial class Chip8Opcode<T> : IOpcode<T> where T : Chip8<T>.Chip8State
{ ... }