使用接口时实现类的特定类型

Dan*_*vil 3 c#

请考虑以下代码示例:

interface IData {
  int Count();
}

interface IOperations {
  IData Foo();
  double Bar(IData a);
}

class Data1 : IData {
  public int Count() { return 37; }
  public double SomethingElse { get; set; }
}

class Ops1 : IOperations 
{
  public Data1 Foo() { return new Data1(); } // want to return specific type here
  public double Bar(Data1 x) { ... } // want to get specific type here
                                     // and not use operator as everywhere
}

// more definitions of classes Data2, Ops2, Data3, Ops3, ...

// some code:
Ops1 a = new Ops1();
Data1 data = a.Foo(); // want Data1 here not IData!
double x = a.Bar(data);
Run Code Online (Sandbox Code Playgroud)

我当然可以使用public IData Foo() { return new Data1(); }:

// some code
Ops1 a = new Ops1();
Data1 data = a.Foo() as Data1;
Run Code Online (Sandbox Code Playgroud)

as随处可见,代码很快变得混乱.

我想知道是否有一个好的设计模式能够以清晰而有力的方式实现这一目标吗?

编辑:重要的是,Ops和Data共享一个公共基类:

List<IOperations> ops = ...;
List<IData> data = ...;
List<double> result = ...;
for(int i=0; i<ops.Count; i++) 
  result[i] = ops[i].Bar(data[i]);
Run Code Online (Sandbox Code Playgroud)

所以对于返回类型的情况,我想知道这是禁止的,因为我满足了接口的要求.在参数的情况下,可能需要一些额外的(模板)层.

Mar*_*ers 5

你可以使用泛型:

interface IOperations<T> where T: IData
{ 
  T Foo();
  double Bar(T a);
}

class Ops1 : IOperations<Data1>
{
    public Data1 Foo() { return new Data1(); }
    public double Bar(Data1 x) { /* ... */  } 
}
Run Code Online (Sandbox Code Playgroud)