Подтвердить что ты не робот

Можете ли вы создать частные классы в С#?

Это вопрос для философов .NET:

Насколько я понимаю, Microsoft сознательно отрицала использование частных классов в С#. Почему они это сделали и каковы их аргументы для этого?

Я, например, создаю большое приложение, которое включает инструмент отчетности. Этот инструмент использует множество бизнес-объектов, которые используются только в инструменте отчетности, а не в других частях проекта. Я хочу инкапсулировать их для использования только в самом инструменте отчетности.

Отличное решение - создать отдельный проект в VS для этого инструмента, и я сделаю вот так, но мне интересно, что делать, если я не смогу этого сделать - для иллюстрации нашей архитектуры недостаточно, и мы имеют большой единый проект.

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

Мой вопрос не был - как я могу имитировать это или делать по-другому. Мне просто интересно, почему бы не использовать личное ключевое слово с ключевым словом без каких-либо родительских классов. Я думаю, что должна быть какая-то причина, и я хочу знать ее

4b9b3361

Ответ 1

Там есть обходной путь, но вам это может не понравиться.

Вместо использования namespace для охвата ваших классов используйте public static partial class:

До:

namespace MyCompany.Foo {
  class Bar { }
  public class Baz { }
}

После:

namespace MyCompany {
  public static partial class Foo {
    private class Bar { }
    public class Baz { }
  }
}

Эта конструкция, подобно пространству имен, может охватывать несколько файлов в одном проекте. Но в отличие от пространства имен он не может "убежать" от вашего проекта (другие проекты не могут определять другие члены внутри Foo).

Там есть дополнительное преимущество, что вы можете иметь утилиты, которые кажется, не имеют класса для кода внутри Foo.

Недостаток заключается в том, что для использования ваших не-частных классов вне вашего поддельного пространства имен вам необходимо ссылаться на них внутри Foo:

using MyCompany;

// ...

var baz = new Foo.Baz();

Это можно смягчить, используя псевдоним для класса:

using Baz = MyCompany.Foo.Baz;

// ...

var baz = new Baz();

Но вам нужно сделать это для каждого не-частного класса, который вы хотите использовать.

UPDATE

Интересно отметить, что С# 6 будет static using statements, что может эффективно улучшить это предложение, чтобы использовать public static partial class как "модуль". Вы просто "используете" "модуль" для непосредственного доступа к его типам.

Надеюсь, он будет работать следующим образом:

using MyCompany.Foo;

// ...

var baz = new Baz();

Как если бы Foo было пространством имен.

Ответ 2

Предоставление классов частным пространствам имен не будет иметь никакого значимого уровня защиты.

Любая сборка в мире может просто ссылаться на вашу DLL и начать писать код в вашем пространстве имен, который обращается к вашим якобы закрытым классам.

Я думаю, что возможно ответ, который вы получите от Microsoft.

Ответ 3

Вы можете создать частный класс как член другого типа:

public class Outer {
  // ...
  private class Inner {
    // ...
  }
}

и Inner видны только членам Outer.

На самом внешнем уровне (т.е. в пространстве имен) private в соответствии с его определением не будет иметь смысла (поскольку в нем нет ничего частного). Вместо этого используйте internal (только для видимых членов сборки).

Ответ 4

Вы можете определить частный класс, но он может использоваться только его содержащим классом.

Если вы хотите, чтобы класс был виден только в определенной сборке (DLL/EXE/etc.), вы должны объявить его как internal (Friend в VB)

Ответ 5

Верно, но вы можете получить довольно близкое моделирование этого с помощью внутренних классов и internalsvisibletoAttribute, если пространство имен разделено на несколько сборок.

Также помните, что класс внутри другого может быть закрытым для внешнего класса. Внешний класс можно считать пространством имен для этой цели.

Ответ 6

Итак, я думаю, вы хотите сделать это

namespace Baz
{
    private class foo
    {
        private int _bar;
    }
}

Если да. Тогда какова цель foo - сервер. В пространстве имен вы можете быть более ограничительным, чем внутреннее, и использовать какой-либо класс. Если я могу это сделать, где я буду использовать это.

Вот почему у вас есть эта проверка времени компиляции.

Теперь внутри публичного класса имеет смысл иметь частный класс. Я не могу объяснить это лучше Частные внутренние классы в С# - почему они не используются чаще?.