我有一个包含一些数据的“最小状态”类型,可以生成另一个最小状态的实例:
public interface IMinimalState
{
IMinimalState generate();
int getData();
}
我还有一个包含更多数据的“正常状态”,可以生成正常状态的实例:
public interface IState
{
IState generate();
int getData();
int getAnotherData();
}
据我所知,IState应该是IMinimalState的子类型。 (任何需要IMinimalState的东西在获得IState时应该同样高兴)但是,我不能让编译器接受它。
示例:
public interface IMinimalState
{
IMinimalState generate();
int getData();
}
public interface IState : IMinimalState
{
int getAnotherData();
}
public class MinimalState : IMinimalState
{
public IMinimalState generate() { return this; }
public int getData() { return 0; }
}
public class State : IState
{
public IState generate() { return this; } //Compiler Error, return type should be IMinimalState
public int getData() { return 1; }
public int getAnotherData() { return 2; }
}
很公平,让我们尝试通用接口:
public interface IMinimalState<out T> where T : IMinimalState<T>
{
T generate();
int getData();
}
public interface IState<out T> : IMinimalState<T> where T : IState<T>
{
int getAnotherData();
}
public class MinimalState : IMinimalState<MinimalState>
{
public MinimalState generate() { return this; }
public int getData() { return 0; }
}
public class State : IState<State>
{
public State generate() { return this; }
public int getData() { return 1; }
public int getAnotherData() { return 2; }
}
尚未编译错误。但State
仍然不是MinimalState
的子类型,IState<State>
不是IMinimalState<MinimalState>
的子类型。我尝试了很多其他组合但没有成功。
有没有办法让IState
成为IMinimalState
的子类型?如果没有,
是不是因为.Net类型系统不够强大?
或者,我认为IState
实际上是IMinimalState
的子类型是错误的吗? (如果某个需要IMinimalState
的内容收到IState
,该程序会崩溃吗?)
答案 0 :(得分:2)
您可以使用new关键字更改generate
的返回类型,然后在generate
类
State
的两种变体形式
public interface IMinimalState
{
IMinimalState generate();
int getData();
}
public interface IState : IMinimalState
{
new IState generate();
int getAnotherData();
}
public class State : IState
{
public IState generate() { return this; }
IMinimalState IMinimalState.generate() { return generate(); }
...
}
答案 1 :(得分:1)
如果您更改了返回类型 - 您正在更改the contract
- 则无法使用IMinimalState
对其进行建模。
我只是简化一下,例如
public interface IMinimalState
{
IMinimalState generate();
int getData();
}
public interface IState : IMinimalState
{
// IState generate();
int getAnotherData();
}
public class MinimalState : IMinimalState
{
public IMinimalState generate() { return this; }
public int getData() { return 0; }
}
public class State : IState
{
IMinimalState IMinimalState.generate() { return this.generate(); }
// IState IState.generate() { return this; }
public IState generate() { return this; }
public int getData() { return 1; }
public int getAnotherData() { return 2; }
}
注意:您的'用例'在这里至关重要(并且缺失) - 并推动您的设计。你应该在做出设计决定之前提供它,这可能是第一件事。
通常,如果您在基础接口IMinimalState
上存储和迭代 - 这就是您所需要的。
如果您正在访问knowing
对象State
,则可以使用其公共方法获取强类型。
如果你仍然想要 - 你可以同时拥有它们(只需取消注释这两行)。
最后一个选项 - 经常用于更复杂的情况 - 是使用Visitor
来区分IMinimalState和IState - 当你只有一个基本接口列表时。例如。你需要redefine
类型的参数,子表达式等表达式使用它。如果你感兴趣我可以稍后发布。
答案 2 :(得分:0)
您需要返回IMinimalState,因为这是界面所说的。
public class State : IState
{
public IMinimalState generate() { return this; } // Fixed
public int getData() { return 1; }
public int getAnotherData() { return 2; }
}
如果您以后需要在IMinimalState的引用上访问IState成员,则需要将其强制转换
var state = minimalState as IState;
if (state != null)
{
// Work on IState
}
答案 3 :(得分:0)
您可以使用泛型:
public interface IMinimalState<T>
{
T generate();
int getData();
}
public interface IState : IMinimalState<IState>
{
IState generate();
int getAnotherData();
}