Можете ли вы создавать частные классы в C #? - PullRequest
23 голосов
/ 26 августа 2010

Это вопрос к философам .NET:

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

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

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

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

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

Ответы [ 6 ]

21 голосов
/ 26 августа 2010

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

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

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

15 голосов
/ 03 сентября 2010

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

Вместо использования 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();

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

ОБНОВЛЕНИЕ

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

Надеюсь, он будет работать так:

using MyCompany.Foo;

// ...

var baz = new Baz();

Так же, как если бы Foo было пространством имен. ** 1043

11 голосов
/ 26 августа 2010

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

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

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

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

2 голосов
/ 26 августа 2010

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

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

1 голос
/ 26 августа 2010

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

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

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

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

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

1 голос
/ 26 августа 2010

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

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

...