通用类型约束不适用
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<> 所要求的),但是通用类型约束似乎不适用于 T
在 Emulator<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
{ ... }
我正在写一个模拟器,我遇到了一个有趣的错误:
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<> 所要求的),但是通用类型约束似乎不适用于 T
在 Emulator<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
{ ... }