我想要实现的目标很简单:对于这样的界面:
public interface ITestInterface
{
void SomeMethod(InputDataBaseClass inputData);
}
我想有多个这样的实现:
public class TestInterfaceImp1 : ITestInterface
{
public void SomeMethod(InputDataDerivedClass1 inputData)
{
}
}
public class TestInterfaceImp2 : ITestInterface
{
public void SomeMethod(InputDataDerivedClass2 inputData)
{
}
}
等等。 InputDataDerivedClass1 和 InputDataDerivedClass2 源自 InputDataBaseClass :
public class InputDataBaseClass
{
}
public class InputDataDerivedClass1 : InputDataBaseClass
{
}
public class InputDataDerivedClass2 : InputDataBaseClass
{
}
所以,最后我可以声明如下:
public class SomeClass
{
public ITestInterface TestInterface { get; set; }
}
注入 TestInterfaceImp1 或 TestInterfaceImp2 ,并使用适当的输入数据类型调用 SomeMethod 。
好的,我意识到我们不能直接做这样的事情,因为接口实现上的方法签名必须匹配。我也意识到常见的解决方法是声明一个通用接口,如下所示:
public interface ITestInterface<T> where T:InputDataBaseClass
{
void SomeMethod(T inputData);
}
public class InputDataBaseClass : ITestInterface<InputDataConcreteClass1>
{
public void SomeMethod(InputDataConcreteClass1 inputData)
{
}
}
但是,这不会编译:
ITestInterface<InputDataBaseClass> t = new InputDataBaseClass();
尽管 InputDataConcreteClass1 继承 InputDataBaseClass ...所以我必须要转换使用 ITestInterface的每个类到通用:
public class SomeClass<T>
{
public ITestInterface<T> TestInterface { get; set; }
}
OR明确声明接口类型:
public class SomeClass
{
public ITestInterface<InputDataConcreteClass1> TestInterface { get; set; }
}
这对整个想法起反作用......或者我错过了什么?
我想我的问题是:还有更好的方法吗?或者这是C#中接口的限制,并且没有办法为不同的实现采用不同的输入数据?
EDIT1:
好的,我知道我可以在实现中使用强制转换:
public class Impl1: ITestInterfaceT
{
public void SomeMethod(InputDataBaseClass inputData)
{
InputDataDerivedClass1 cast = inputData as InputDataDerivedClass1;
System.Console.WriteLine(cast.A);
System.Console.WriteLine(cast.B);
}
}
public class Impl2 : ITestInterfaceT
{
public void SomeMethod(InputDataBaseClass inputData)
{
InputDataDerivedClass2 cast = inputData as InputDataDerivedClass2;
System.Console.WriteLine(cast.A);
System.Console.WriteLine(cast.C);
}
}
public interface ITestInterfaceT
{
void SomeMethod(InputDataBaseClass inputData);
}
public class InputDataBaseClass
{
public string A { get; set;}
}
public class InputDataDerivedClass1 : InputDataBaseClass
{
public string B { get; set;}
}
public class InputDataDerivedClass2 : InputDataBaseClass
{
public string C { get; set;}
}
但这正是我想要避免的;没有编译时类型检查,这将是一个相当脆弱的代码 - 还有更好的方法吗?
EDIT2:
我面临的问题是我的接口的实现必须实现一个处理相同逻辑但在每个实现中使用稍微不同的输入数据的方法。 例如,我有方法 SaveData - 一个实现将其保存到数据库并需要数据和一组外键,而另一个实现将其保存到磁盘并需要数据加上文件名。到目前为止,我总是通过在实现的构造函数中插入所有必需的数据然后调用SaveData方法(无参数或使用单个参数)来完成它,如下所示:
public interface IDataSaver
{
void SaveData(string someData);
}
public class ToDiskDataSaver : IDataSaver
{
private string FilePath { get; set;}
public ToDiskDataSaver(string filePath)
{
this.FilePath = filePath;
}
public void SaveData(string someData)
{
//save file to disk here
}
}
public class ToDatabaseDataSaver : IDataSaver
{
private long DataForeignKey { get; set; }
public ToDatabaseDataSaver(long dataForeignKey)
{
this.DataForeignKey = dataForeignKey;
}
public void SaveData(string someData)
{
//save file to database here
}
}
等等。
这完美地工作 ...但是当一个方法需要复杂的输入参数时,我正在寻找一种方法使它工作 - 每个实现都不同(不在构造函数中插入它们)。也许这不可能做到......