为什么静态类不能实现接口?

Bor*_*ens 96 .net c#

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

在我的应用程序中,我想使用一个将执行原始数据访问的存储库(TestRepository,SqlRepository,FlatFileRepository等).因为这样的存储库将在我的应用程序的整个运行时间中使用,所以对我来说这是一个明智的事情,让它成为一个静态的类,所以我可以去

SqlRepository.GetTheThingById(5);
Run Code Online (Sandbox Code Playgroud)

没有它必须一直重生.因为我希望我的存储库可以互换,所以我想它们实现一个通用接口:IRepository.但是当我尝试这样做时,我明白了

"Static classes cannot implement interfaces"
Run Code Online (Sandbox Code Playgroud)

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

更新
五年后:这个问题被访问了20k +次,我了解了存储库模式的缺点,了解了IoC,并意识到我的问题制定得很差.

我真的不是在问接口的C#规范是什么,而是为什么它故意以这种特定的方式限制我.

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

Joe*_*ite 43

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

  • 正确但不是"为什么"问题的答案 (74认同)
  • @Heliac:如果观众不接受这个场所,这不是一个有说服力的论点.如果鲍里斯明白为什么这个前提是真的,为什么地球上他不明白为什么静态类不能实现接口呢? (27认同)
  • 那么问题就是为什么接口不能有静态方法(或者为什么接口方法不能被视为静态和实例,这取决于它们是如何实现的)?这基本上可以追溯到原来的问题.当重言式作为答案时,往往会发生这种情况. (11认同)
  • 实际上,就是这样.每个句子逻辑上导致下一个.再次阅读他的答案,分析它,让它沉入;-) (9认同)
  • 不回答为什么。假设您可以在静态类中实现一个接口,您将如何使用它?您不能传递对静态类的引用,因此您不能拥有一堆具有签名的方法或类,该签名采用接口而不是特定类型。因此,您不能使用该类进行依赖注入,而这正是您可能希望对接口执行的操作。为什么 C# 不将静态类视为隐式为单例的类,以便您可以传递它,这是我无法回答的另一个问题。 (2认同)

n8w*_*wrl 18

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

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

通过这种方式,我们可以交换实现,并且调用者总是知道从哪里获取它:

Part p = Part.Repository.Get(id);
Run Code Online (Sandbox Code Playgroud)

在另一个项目中,有一个使用容器注册的PartRepository:

public class PartRepository : IPartRepository
{
    // IPartRepository implementation that talks to injected DAL
}
Run Code Online (Sandbox Code Playgroud)

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

public class MockPartRepository : Dictionary<Part, int>, IPartRepository
{
    // IPartRepository implementation based on dictionary
}
Run Code Online (Sandbox Code Playgroud)

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

Part p = Part.Repository.Get(id);
Run Code Online (Sandbox Code Playgroud)


Jos*_*dan 13

根据定义,接口为要实现的实例创建合同.由于无法实例化静态类,因此静态类无法实现接口.

无需拥有静态存储库.只需将其设置为非静态,并在需要时进行实例化.

  • 根据定义,接口创建联系人(例如,可以调用的方法).静态类具有可以调用的方法.自我:静态类可以履行合同. (16认同)
  • 通用接口定义确实如此,但是这个问题与C#有关,其中您的定义不完整。 (2认同)