通用类型约束不适用

时间:2015-01-21 03:09:59

标签: c# generics inheritance

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

  

错误CS0311:类型&#39; T&#39;不能用作类型参数&#39; T&#39;在通用类型或方法'Emulator.Emulator<T>'中。来自&#39; T&#39;没有隐式参考转换。到'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&lt;&gt;所要求的),但似乎泛型类型约束不适用于{{1在T中,因为错误是&#34;类型&#39; T&#39;&#34;而不是&#34;类型&#39; Chip8State&#39;。&#34;这是编译中的错误还是有更好的方法将类型约束应用于继承的泛型?

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

另外:如果以后需要,可以使用泛型来容易地扩展模拟器,尽管知道是否有更好的方法可以做到这一点很好。

2 个答案:

答案 0 :(得分:3)

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

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
{ ... }

答案 1 :(得分:2)

你能不能这样说:

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

另外,检查关于“仿制药中的协方差和逆变”的主题。只能在某种程度上使用C#中的接口。