104

可能重复:
为什么 C# 不允许静态方法实现接口?

在我的应用程序中,我想使用一个存储库来进行原始数据访问(TestRepository、、SqlRepositoryFlatFileRepository)。因为这样的存储库将在我的应用程序的整个运行时使用,所以将它设置为静态类对我来说似乎是明智之举,这样我就可以去

SqlRepository.GetTheThingById(5);

无需一直重新生成它。因为我希望我的存储库是可互换的,所以我希望它们实现一个通用接口:IRepository. 但是当我尝试这样做时,我得到:

静态类不能实现接口

为什么他们不能?你如何建议我改变我的设计呢?有我可以使用的模式吗?

更新
五年后:这个问题被访问了 20k+ 次,我了解了存储库模式的缺点,了解了 IoC 并意识到我的问题表述得很糟糕。

我并没有真正问接口的 C# 规范是什么,而是为什么它故意以这种特定方式限制我。

实际的答案是在实例或类型上调用方法的语法是不同的。但问题已经结束。

4

3 回答 3

43

接口不能有静态方法。实现接口的类需要将它们全部实现为实例方法。静态类不能有实例方法。QED。

于 2009-08-12T14:15:52.003 回答
18

也许我们的经验会有所帮助。我们没有将 SqlRepository 作为静态类,而是使用 AutoFac 进行注入并将容器隐藏在静态类后面。然后每个实体都有一个静态存储库属性:

public class Part : inheritence...
{
    public static IPartRepository Repository
    {
        get { return IoCContainer.GetInstance<IRepository<Part>>(); }
    }
    // ... more part-y stuff
}

这样我们就可以换出实现,调用者总是知道从哪里得到它:

Part p = Part.Repository.Get(id);

在另一个项目中,在容器中注册了一个 PartRepository:

public class PartRepository : IPartRepository
{
    // IPartRepository implementation that talks to injected DAL
}

在另一个项目中,我们有用于测试的模拟,包括预加载已知整体的存储库:

public class MockPartRepository : Dictionary<Part, int>, IPartRepository
{
    // IPartRepository implementation based on dictionary
}

...并且它已在容器中注册以进行单元测试。SAME 调用获取存储库:

Part p = Part.Repository.Get(id);
于 2009-08-12T14:16:32.627 回答
13

根据定义,接口为要履行的实例创建契约。由于您无法实例化静态类,因此静态类无法实现接口。

不需要有静态存储库。只需将其设为非静态并在需要时对其进行实例化。

于 2009-08-12T14:17:13.060 回答