1

我有一个“最小状态”类型,其中包含一些数据并且可以生成另一个最小状态实例:

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仍然不是 的子类型MinimalStateIState<State>也不是 的子类型IMinimalState<MinimalState>。我尝试了许多其他组合,但没有成功。

有没有办法制作IState的子类型IMinimalState?如果不,

  • 是因为.Net类型系统不够强大吗?

  • 或者,我认为这IState真的是 的子类型是错误的IMinimalState吗?(如果需要的东西IMinimalState接收到,程序是否会崩溃IState?)

4

4 回答 4

2

您可以使用 new 关键字来更改 的返回类型generate,然后generateState类中实现两种变体

   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(); }           
      ...
   }
于 2013-04-24T11:41:01.457 回答
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你可以使用它的公共方法来获取强类型。

如果您仍然想要 - 您可以同时拥有(只需取消注释这两行)。

最后一个选项 - 通常用于更复杂的情况 -是使用 aVisitor来区分 IMinimalState 和 IState - 当您只有一个基本接口列表时。例如,在您需要redefine参数类型、子表达式等的表达式中使用它。如果您有兴趣,我可以稍后发布。

于 2013-04-25T16:17:41.723 回答
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
}
于 2013-04-24T11:47:20.343 回答
0

您可以使用泛型:

public interface IMinimalState<T>
{
    T generate();
    int getData();
}

public interface IState : IMinimalState<IState>
{
    IState generate();
    int getAnotherData();
}
于 2013-04-24T11:48:01.823 回答