Абстрактный класс не может быть запечатан в С#?

Я где-то читал

"Абстрактные и Запечатанные модификаторы эквивалентны классу, статическому"

Я также обнаружил, что

"Когда вы объявляете статический класс, внутри компилятор отмечает абстрактное и закрытое имя класса и создает частный конструктор в коде IL

Итак, я решил сделать это:

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

Теперь класс "A" не может быть унаследован и не создан.

Итак, напишем class B с помощью abstract, чтобы предотвратить создание экземпляра и использовать sealed для предотвращения наследования.

Но этот подход терпит неудачу.

который должен быть эквивалентен

public abstract sealed class B
{
    private B()
    {

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

But I recieve an error stating "error CS0418: B ': абстрактный класс не может быть запечатан или статичным ". Любые идеи, почему это невозможно?

Заранее благодарим за ваши ответы.

Ответ 1

Проверяя IL класса System.Directory(который является статическим), он объявляется в IL как:

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

Кроме того, эта статья (http://msdn.microsoft.com/en-us/library/ms229038.aspx) предполагает, что CLR обрабатывает статические классы как абстрактные закрытые классы для поддержки языков, которые не поддерживают напрямую декантирование статических классов (например, С++).

Таким образом, статические классы в С# являются синтаксическим сахаром для закрытых абстрактных классов с частными конструкторами. Я рад этому, потому что "статический" намного проще писать и намного легче получить право.

Ответ 2

По определению класс sealed позволяет предотвратить наследование класса или определенных членов класса, которые были ранее отмечены как виртуальные.

Ключевое слово

Abstract позволяет вам создавать классы и члены класса, которые являются неполными и должны быть реализованы в производном классе. (Источник: http://msdn.microsoft.com/en-us/library/ms173150.aspx)

Это означало бы, что любой класс, отмеченный абстрактом, не сможет быть запечатан, поскольку вы не сможете его извлечь нигде.

Указанный вами код не имеет никакого смысла.

Ответ 3

Все ответы как-то берут техническую точку зрения. Например: класс не может быть "наследовать" и "не может наследовать" одновременно. Но я думаю, что это не главная причина, так как ясно, что это "статичность". Я думаю, что ответ Дэвида Амо немного коснулся реального ответа, заявив: "Намного легче добиться успеха".

Я убежден, что идея Андерса Хейльсберга при проектировании С# заключалась в устранении двусмысленности и, таким образом, уменьшении вероятности ошибки. Вот почему "виртуальный" идет с "переопределением" (переопределение должно быть явным, а не подразумеваемым, как в Java). И в этом случае "абстрактный" + "запечатанный" будет таким же, как "статический". Два способа определения одного и того же принципа. Это: - больше подвержено ошибкам (представьте, что вы где-то абстрагированы и помещаете там запечатанные случайно, не замечая, компилятор onw предотвращает это) - сложнее работать (представьте, что вы хотите искать все статические классы в своем проекте)

Итак, я хочу сказать, что весь этот проект заставляет разработчиков правильно делать вещи.