我正在编写两个API,我将与许多项目一起使用。有些项目使用了其中一个API,另一些则使用了其中一些,但我的大部分项目都将使用这两个API。我试图将它们设计成好像它们完全分开,但我在一件事上挣扎着。具有相同通用方法的抽象类和接口
namespace FirstApi {
public abstract class MyBaseClass {
//constructor, some methods and properties
public IEnumerable<T> Search<T>() where T : MyBaseClass, new() {
//search logic here. must use generics as I create new instances of T here
}
}
}
namespace SecondApi {
public interface IMyInterface {
//some property and method signatures
IEnumerable<T> Search<T>() where T : IMyInterface, new();
}
}
namespace MyProject {
public class MyDerivedClass : MyBaseClass, IMyInterface {
}
}
这两个API都需要这种搜索方法。第二个API在调用IMyInterface.Search<T>()
的其他类中有一些功能,我希望那些继承MyBaseClass
的类使用MyBaseClass
中定义的Search<T>
函数。
编译错误:类型参数方法的“T”“MyBaseClass.Search()”的约束必须为类型参数界面方法的“T”“IMyInterface.Search()”的约束条件相匹配。考虑使用显式接口实现。
注意:当搜索被调用时,T将永远是任何抽象类或接口已被继承的派生类。这是我在C#2.0(C# abstract class return derived type enumerator)中实现这一目标的唯一方法,它只是造成了更多问题!
有没有一种类型安全的方式,我可以实现这一点,而不使用对象和铸造?
解决方案:基于由安德拉斯·佐尔坦接受的答案
,我在我的项目创造了这个班,并且将不得不重新创建这个类为使用这两个API每个项目。
public abstract class ApiAdapter<TAdapter> : MyBaseClass, IMyInterface where TAdapter: MyBaseClass, IJsonObject, new()
{
IEnumerable<T> IJsonObject.Search<T>()
{
foreach (TAdapter row in base.Search<TAdapter>())
yield return (T)(IMyInterface)row;
}
}
然后我就像这样继承这个类。
public class Client : ApiAdapter<Client> {
//everything else can go here
}
也许它在清晨,我都还没有苏醒过来,但我不明白问题是什么。为什么你提供的代码不工作? – 2011-05-25 09:11:29
对不起,我更新了编译器错误的帖子 – Connell 2011-05-25 09:16:46
对不起,我也不明白这个问题。也许提供一个真实世界的例子,而不是'IMyInterface'和'MyBaseClass'可以提供帮助。 – 2011-05-25 09:17:00