|
|
1
208
假设你问为什么你不能这样做:
从语义上讲,这对我来说没有意义。接口上指定的方法应该用于指定与对象交互的契约。静态方法不允许您与对象交互——如果您发现自己处于可以使实现静态的位置,您可能需要问自己该方法是否真的属于接口。 为了实现你的例子,我会给Animal一个const属性,它仍然允许从静态上下文访问它,并在实现中返回该值。
对于更复杂的情况,您始终可以声明另一个静态方法并委托给该方法。在尝试举一个例子时,我想不出任何理由,你会在静态和实例上下文中做一些非平凡的事情,所以我会给你一个FooBar blob,并将其视为一个可能不是好主意的迹象。 |
|
|
2
159
我的(简化的)技术原因是静态方法不在 vtable ,并且在编译时选择调用站点。这也是你不能有覆盖或虚拟静态成员的原因。要了解更多细节,你需要一个计算机科学毕业生或编译器专家——我两者都不是。 出于政治原因,我会 quote Eric Lippert (他是一名编译器专家,拥有滑铁卢大学数学、计算机科学和应用数学学士学位(来源: LinkedIn ):
请注意,Lippert确实为所谓的类型方法留出了空间:
但尚未确信其有用性。 |
|
|
3
86
这里的大多数答案似乎都没有抓住重点。多态性不仅可以在实例之间使用,还可以在类型之间使用。当我们使用泛型时,这是经常需要的。 假设我们在泛型方法中有类型参数,我们需要对它做一些操作。我们不想实例化,因为我们不知道构造函数。 例如:
不幸的是,我只能想出“丑陋”的替代方案:
例子:
为了使用实例化来解决静态接口问题,我们需要做以下事情:
这显然是丑陋的,也不必要地使所有其他方法的代码复杂化。显然,这也不是一个优雅的解决方案! |
|
|
4
18
我知道这是一个老问题,但很有趣。这个例子不是最好的。我认为如果你展示一个用例会更清楚: string DoSomething<T>() where T:ISomeFunction
{
if (T.someFunction())
...
}
仅仅能够拥有静态方法 实施 一个界面不会达到你想要的效果;需要的是拥有静态成员 部分 一个接口。我当然可以想象很多用例,尤其是在能够创造东西的时候。我可以提供两种可能有所帮助的方法:
这些方法都没有真正的吸引力。另一方面,我希望,如果CLR中存在干净地提供这种功能的机制,.net将允许指定参数化的“新”约束(因为知道一个类是否有一个具有特定签名的构造函数似乎与知道它是否具有一个具有特定签名的静态方法的难度相当)。 |
|
|
5
14
我猜是近视。 最初设计时,接口仅用于类的实例
只有引入接口作为泛型的约束,向接口添加静态方法才有实际用途。 (回应评论:)我认为现在更改它需要更改CLR,这将导致与现有程序集不兼容。 |
|
|
6
13
就接口代表“契约”而言,静态类实现接口似乎是合理的。 上述论点似乎都忽略了合同的这一点。 |
|
|
7
12
接口指定对象的行为。 静态方法不指定对象的行为,而是以某种方式影响对象的行为。 |
|
|
8
8
因为接口的目的是允许多态性,能够传递任意数量的已定义类的实例,这些类都已定义以实现已定义的接口。..保证在您的多态调用中,代码能够找到您正在调用的方法。允许静态方法实现接口是没有意义的, 你怎么称呼它??
|
|
|
9
4
事实上,确实如此。
截至2022年中期,当前版本的C#完全支持所谓的
请注意,这取决于您的Visual Studio版本和安装的版本。NET SDK,您必须至少更新其中一个(或两者都更新),或者必须启用预览功能(请参阅 Use preview features & preview language in Visual Studio ). 查看更多:
|
|
|
10
3
关于在非泛型上下文中使用的静态方法,我同意在接口中允许它们没有多大意义,因为如果你有对接口的引用,你就无法调用它们。然而,在语言设计中存在一个根本性的漏洞,即不是在多态上下文中使用接口,而是在通用上下文中使用。在这种情况下,接口根本不是接口,而是约束。因为C#在接口之外没有约束的概念,所以它缺少实质性的功能。一个恰当的例子:
这里没有多态性,泛型使用对象的实际类型并调用+=运算符,但这失败了,因为它不能确定该运算符是否存在。简单的解决方案是在约束中指定它;简单的解决方案是不可能的,因为运算符是静态的,静态方法不能在接口中,而且(这就是问题所在)约束被表示为接口。 C#需要的是一个真正的约束类型,所有的接口都是约束,但并非所有的约束都是接口,那么你可以这样做:
已经有很多关于为所有数值类型实现IArithmetic的讨论,但人们担心效率,因为约束不是多态结构,所以制作CArithmetic约束可以解决这个问题。 |
|
|
11
3
因为接口是继承结构,静态方法不能很好地继承。 |
|
|
12
3
您似乎想要的是允许通过Type或该类型的任何实例调用静态方法。这至少会导致歧义,这不是一个理想的特征。 关于这是否重要、哪种是最佳实践以及以这种或那种方式进行是否存在性能问题,将会有无休止的争论。通过简单地不支持它,C#让我们不用担心它。 符合这种愿望的编译器也可能会失去一些优化,而这些优化可能会带来实例和静态方法之间更严格的分离。 |
|
|
13
3
您可以将类的静态方法和非静态方法视为不同的接口。当被调用时,静态方法会解析为单例静态类对象,非静态方法则解析为所处理类的实例。因此,如果你在一个接口中使用静态和非静态方法,当我们真的希望接口用于访问一个有凝聚力的东西时,你实际上是在声明两个接口。 |
|
|
14
1
举一个例子,我缺少接口方法的静态实现,或者Mark Brackett引入的“所谓的类型方法”: 当从数据库存储中读取时,我们有一个通用的DataTable类,可以处理从任何结构的表中读取。所有特定于表的信息都放在每个表的一个类中,该类还保存数据库中一行的数据,并且必须实现一个ViewModel row接口。ViewModel Row中包含对要从数据库读取的表的结构的描述。DataTable在从数据库读取数据之前,必须先从ViewModel Row请求数据结构。目前情况如下:
每个表只需要读取一次GetDataStructure,实例化多个实例的开销很小。然而,在这种情况下,这将是一件好事。 |
|
|
15
1
从c#9开始,允许在接口中使用静态方法(参见 https://www.dotnetcurry.com/csharp/simpler-code-with-csharp-9 ). |
|
|
16
1
仅供参考:通过为接口创建扩展方法,您可以获得与所需类似的行为。扩展方法将是一种共享的、不可重写的静态行为。然而,不幸的是,这种静态方法不是合同的一部分。 |
|
|
17
1
接口是定义的可用功能的抽象集合。 该接口中的方法是否表现为静态是一个应该隐藏在接口后面的实现细节 .将接口方法定义为静态是错误的,因为这样会不必要地强制以某种方式实现该方法。 如果方法被定义为静态的,那么实现接口的类就不会被尽可能地封装。在面向对象的设计中,封装是一件值得努力的事情(我不会详细说明为什么,你可以在这里阅读: http://en.wikipedia.org/wiki/Object-oriented ).因此,接口中不允许使用静态方法。 |
|
|
18
1
静态类应该能够做到这一点,这样它们就可以通用。我不得不实施Singleton来实现预期的结果。 我有一堆静态业务层类,它们为每种实体类型(如“用户”、“团队”等)实现了CRUD方法,如“创建”、“读取”、“更新”、“删除”。然后,我创建了一个基本控件,该控件具有实现CRUD方法的业务层类的抽象属性。这使我能够从基类中自动执行“创建”、“读取”、“更新”、“删除”操作。由于静态限制,我不得不使用Singleton。 |
|
|
19
1
大多数人似乎忘记了,在面向对象编程中,类也是对象,因此它们有消息,出于某种原因,c#调用了“静态方法”。 实例对象和类对象之间存在差异的事实只表明了语言的缺陷或不足。 对c#持乐观态度。.. |
|
|
20
0
好的,这里有一个需要“类型方法”的例子。我正在基于一些源XML创建一组类中的一个。所以我有一个
在每个类上依次调用的函数。 函数应该是静态的,否则我们会浪费时间创建不合适的对象。 正如@Ian Boyde所指出的,这可以在工厂类中完成,但这只会增加复杂性。 将它添加到接口中以强制类实现者实现它会很好。这不会造成显著的开销——它只是一个编译/链接时间检查,不会影响vtable。 然而,这也将是一个相当小的改进。由于该方法是静态的,作为调用者,我必须显式调用它,因此如果没有实现,就会立即出现编译错误。允许在接口上指定它意味着这个错误在开发周期的早期出现,但与其他损坏的接口问题相比,这是微不足道的。 因此,这是一个次要的潜在特征,总的来说,最好忽略不计。 |
|
|
21
0
微软在C#中创建了一个带有静态元素的类的特殊实例来实现静态类,这只是实现静态功能的一个奇怪之处。这不是一个理论问题。 接口应该是类接口的描述符,或者它是如何与之交互的,并且应该包括静态的交互。界面的一般定义(来自梅里亚姆·韦伯斯特):不同事物相遇、交流或相互影响的地方或区域。当你完全省略一个类或静态类的静态组件时,我们忽略了这些坏男孩如何互动的大部分内容。 下面是一个非常清楚的例子,说明能够使用静态类的接口在哪些方面非常有用:
目前,我编写包含这些方法的静态类,而不进行任何检查,以确保我没有忘记任何事情。就像OOP之前糟糕的编程时代。 |
|
|
22
0
C#和CLR应该像Java一样支持接口中的静态方法。静态修饰符是合约定义的一部分,确实有意义,具体来说,行为和返回值不会因实例而异,尽管它可能仍因调用而异。 也就是说,我建议当你想在接口中使用静态方法但无法使用时,使用注释代替。您将获得所需的功能。 |
|
|
23
0
我认为简短的回答是“因为它毫无用处”。 要调用接口方法,您需要该类型的实例。从实例方法中,您可以调用任何想要的静态方法。 |
|
|
24
0
我认为问题在于C#需要另一个关键字,正是为了这种情况。你想要一个返回值仅取决于调用它的类型的方法。如果所述类型未知,则不能称之为“静态”。但一旦知道类型,它就会变成静态的。“未解决的静态”是一个想法——它还不是静态的,但一旦我们知道接收类型,它就会是静态的。这是一个非常好的概念,这就是为什么程序员一直在要求它。但它并不完全符合设计师对语言的思考方式。 由于它不可用,我开始使用非静态方法,如下所示。不太理想,但我看不出任何更有意义的方法,至少对我来说没有。
|
|
jlandercy · PostgreSQL参数化窗口大小 8 年前 |