为啥静态类不能实现接口? [复制]
Posted
技术标签:
【中文标题】为啥静态类不能实现接口? [复制]【英文标题】:Why static classes cant implement interfaces? [duplicate]为什么静态类不能实现接口? [复制] 【发布时间】:2010-11-18 23:32:40 【问题描述】:可能重复:Why Doesn’t C# Allow Static Methods to Implement an Interface?
在我的应用程序中,我想使用一个存储库来访问原始数据(TestRepository
、SqlRepository
、FlatFileRepository
等)。
因为这样的存储库将在我的应用程序的整个运行时使用,所以将其设置为静态类对我来说似乎是明智之举,这样我就可以去
SqlRepository.GetTheThingById(5);
不必一直重新生成它。
因为我希望我的存储库可以互换,所以我希望它们实现一个通用接口:IRepository
。
但是当我尝试这样做时,我得到:
静态类不能实现接口
他们为什么不能? 你如何建议我改变我的设计呢?有没有我可以使用的模式?
更新 五年后:这个问题被访问了 20k+ 次,我了解了存储库模式的缺点,了解了 IoC 并意识到我的问题表述得很糟糕。
我并没有真正问接口的 C# 规范是什么,而是为什么它故意以这种特定方式限制我。
实际的答案是在实例或类型上调用方法的语法是不同的。但是问题已经结束了。
【问题讨论】:
我认为是***.com/questions/259026 的副本。 如果您的帖子没有因为重复而关闭,您可以更改继承来实现吗?烦死我了…… 复制:***.com/questions/3957424/… @MichaelStum 这不是其中任何一个的副本。这些是关于静态方法实现由这些方法所属的类实现的接口指定的方法。这个问题是关于实现接口的静态类。 我为链接的副本写了一个答案,但由于它实际上是这个问题的答案,所以对那个问题没有意义,我不能在这里发布它,因为它被错误地关闭了.我宁愿不必打开一个实际的副本。 【参考方案1】:也许我们的经验会有所帮助。我们没有将 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);
【讨论】:
您能详细说明一下吗?还有一些代码? @moontear:我们已经切换到 AutoFac,但概念是一样的。查看编辑以回答 哇,希望我能投票更多。 3 年后更新:-) 我们正在使用 Spring.Net,我正在考虑只使用单例(用于日志框架)而不是构建完整的存储库。否则我喜欢你的解决方案!【参考方案2】:根据定义,接口为要履行的实例创建契约。由于不能实例化静态类,静态类不能实现接口。
没有必要拥有一个静态存储库。只需将其设为非静态并在需要时对其进行实例化。
【讨论】:
根据定义,接口创建联系人(例如可以调用的方法)。静态类有可以调用的方法。自我:静态类可以履行契约。 泛型接口定义确实如此,但这个问题是关于C#的,其中你的定义不完整。【参考方案3】:接口不能有静态方法。实现接口的类需要将它们全部实现为实例方法。静态类不能有实例方法。 QED。
【讨论】:
正确但不是“为什么”问题的答案 其实就是这样。每个句子在逻辑上都通向下一个句子。再次阅读他的答案,分析它,让它沉入;-) @Heliac:如果观众不接受前提,这不是一个有说服力的论点。如果鲍里斯明白为什么这个前提是正确的,为什么他不明白为什么静态类不能实现接口? 那么问题就是为什么接口不能有静态方法(或者为什么接口方法不能同时被视为静态和实例,这取决于它们是如何实现的)?这基本上可以追溯到最初的问题。当给出重言式作为答案时,往往会发生这种情况。 不回答原因。假设您可以在静态类中实现接口,您将如何使用它?您不能传递对静态类的引用,因此您不能有一堆方法或类具有采用接口而不是特定类型的签名。因此,您不能使用该类进行依赖注入,而这正是您可能想要对接口执行的操作。为什么 C# 不将静态类视为隐式为单例的类,以便您可以传递它是另一个我无法回答的问题。以上是关于为啥静态类不能实现接口? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
为啥静态成员函数只能在类定义中声明为静态,而不能在其自己的定义中声明?
为啥编译包含静态嵌套类的类会创建一个名为“EnclosureClass$1”的新 .class 文件? [复制]