6

我在某处读过

“抽象和密封修饰符相当于一个静态类”

我还发现

“当你声明一个静态类时,编译器在内部标记类抽象和密封,并在 IL 代码中创建一个私有构造函数”

所以,我决定这样做:

static class A
{
    public static void test()
    {
        Console.WriteLine("test");
    }
}

现在,类“A”不能被继承也不能被实例化。

所以,让我们写一个class Busingabstract来防止实例化和 usingsealed来防止继承。

但是,这种方法失败了。

这应该相当于

public abstract sealed class B
{
    private B()
    {

    }
    public void test()
    {
        Console.WriteLine("test");
    }
}

But I recieve an error stating "error CS0418:B':一个抽象类不能是密封的或静态的”`。任何想法为什么这是不可能的?

提前感谢您的回答。

4

3 回答 3

11

在检查了 System.Directory 类(它是静态的)的 IL 之后,它在 IL 中声明为:

.class public auto ansi abstract sealed beforefieldinit System.IO.Directory
extends System.Object
{
    ...

此外,这篇文章 ( http://msdn.microsoft.com/en-us/library/ms229038.aspx ) 建议 CLR 将静态类作为抽象密封类处理,以支持不支持直接删除静态类的语言(例如 C++ )。

因此,总而言之,C# 中的静态类是具有私有构造函数的密封抽象类的语法糖。我对此感到高兴,因为“静态”更容易编写,也更容易正确。

于 2013-10-16T13:57:47.677 回答
3

根据定义,sealed类使您能够阻止以前标记为虚拟的类或某些类成员的继承。

Abstract关键字使您能够创建不完整且必须在派生类中实现的类和类成员。(来源:http: //msdn.microsoft.com/en-us/library/ms173150.aspx

这意味着任何标记为抽象的类都无法被密封,因为您无法在任何地方派生它。

你提到的代码没有任何意义。

于 2013-10-16T13:23:50.367 回答
1

所有答案都以某种方式从技术角度出发。如:类不能同时“必须继承”和“不能继承”。但我认为这不是主要原因,很明显,“静态”就是这样。我认为大卫·阿莫的回答有点触及到真正的答案,他说:“做对要容易得多”。

我相信 Anders Hejlsberg 在设计 C# 时的想法是消除歧义,从而减少出错的机会。这就是为什么“虚拟”与“覆盖”一起使用(覆盖必须是显式的,而不是 Java 中的隐式)。在这种情况下,“抽象”+“密封”将与“静态”相同。定义同一原则的两种方式。这是: - 更容易出错(想象你在某处有抽象并在没有注意到的情况下意外地把它密封在那里,onw 编译器会阻止它) - 更难使用(想象你想搜索项目中的所有静态类)

所以我的观点是,整个设计引导开发人员正确的做事方式。

于 2016-09-12T08:34:23.440 回答