Как сделать код инфраструктуры видимым только в пространстве имен?


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

namespace MathematicalParser {
  public class ExpressionParser {
    public ExpressionParser(string expression, List<string> variables);
    public double GetNumericValue(Dictionary<string,double> variableValues);
  }
}

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

В попытке улучшить ремонтопригодность кода я пытаюсь отдельный код, который логически не связан с их собственными классами, эти классы, однако, не имеют никакого значения за пределами ExpressionParser, поэтому я хотел бы ограничить их видимость пространством имен MathematicalParser (которое содержит только ExpressionParser).

Как лучше всего сделать это в c#, внутреннее ключевое слово работает только на сборках и private не может использоваться в пространствах имен.

3 3

3 ответа:

Я бы не стал этого делать (то же мнение, что и Джо), но вот еще одно решение, полученное из ответа Лопины: вложенные классы + частичные классы.

Публичный класс.cs:

namespace MyNamespace
{
    public partial class PublicClass
    {
        public int ReturnSomeStuff()
        {
            MyHelperClass1 tmp = new MyHelperClass1();
            MyHelperClass2 tmp2 = new MyHelperClass2();

            return tmp.GetValue1() + tmp2.GetValue2();
        }
    }
}

PrivateClass1.cs:

namespace MyNamespace
{
    public partial class PublicClass
    {
        private class MyHelperClass1
        {
            public int GetValue1()
            {
                return 5;
            }
        }
    }
}

PrivateClass2.cs:

namespace MyNamespace
{
    public partial class PublicClass
    {
        private class MyHelperClass2
        {
            public int GetValue2()
            {
                return 10;
            }
        }
    }
}

Программа.cs:

public class Program
{
    private static void Main(string[] args)
    {
        PublicClass tmp = new PublicClass();

        MyHelperClass2 zz;  // Can't access MyHelperClass2 here cause it's private

        Console.WriteLine(tmp.ReturnSomeStuff());
        Console.ReadLine();
    }
}

Как вы можете видеть, ваши различные вспомогательные классы физически разделены в разных файлах (возможно, это поможет вам поддерживать ваш код). И вы не можете получить к ним прямой доступ, они являются частными для PublicClass.

Вы пробовали использовать частные вложенные классы?
Посмотрите сюда: частные внутренние классы в C# - почему они не используются чаще?

Если вы действительно отчаянно хотите сделать это (в свете моего комментария к исходному вопросу), вы можете поместить все вспомогательные классы в одну сборку и сделать их внутренними, чтобы они были эффективно закрыты от использования. Затем сделайте вторую сборку, ту, которую вы позволяете людям использовать, и поместите "открытые" классы и методы во вторую сборку. Затем используйте InternalsVisibleTo, чтобы разрешить вашей "публичной" сборке использовать вспомогательные классы другой "частной" сборки и методы.

Http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx

Это означает, что вы должны заставить людей, использующих вашу библиотеку, работать в другой сборке, чем та, в которой содержится ваш "публичный" библиотечный код. Я думаю, что из вашего вопроса Вы говорите, что они работают в одной и той же ассамблее, и в этом случае вам придется отделить "публичную" библиотеку в другую ассамблею. И если ты это сделал, то... просто сделать методы внутренними и поместить их в одну и ту же сборку, в конце концов, сделает свою работу.

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

И если этого недостаточно ... Я не знаю, написать веб-сервис WCF и работать через это*.

*это была сатира