Reputation: 23031
Consider the following code sample:
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);
I could of course just use public IData Foo() { return new Data1(); }
:
// some code
Ops1 a = new Ops1();
Data1 data = a.Foo() as Data1;
but with as
everywhere, the code is quickly becoming confusing.
I wonder if there is a good design pattern to achieve this in a clear and strong way?
Edit: Is is important, that Ops and Data share a common base class:
List<IOperations> ops = ...;
List<IData> data = ...;
List<double> result = ...;
for(int i=0; i<ops.Count; i++)
result[i] = ops[i].Bar(data[i]);
So for the case with the return type, I wonder that this is forbidden, because I satisfy the requirement of the interface. In the case with parameters probably there is some additional (template) layer required.
Upvotes: 3
Views: 99
Reputation: 839194
You could use generics:
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) { /* ... */ }
}
Upvotes: 5