How do you make infrastructure code only visible in namespace?

a 夏天 提交于 2019-12-10 19:57:59

问题


I have an implementation of the Shunting-Yard algorithm that I am trying to integrate clearly into our framework. Currently I have it all packed into a class with a simple public interface.

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

Inside this class there are a lot of helper classes, helper enums, static variables etc to map different names to functions. All these are private so that is no concern to the user of the library.

In an effort to improve maintainability of the code I'm trying to separate code that is logically unrelated into their own classes, these classes do however not have any meaning outside of the ExpressionParser so I'd like to limit their visibility to the namespace MathematicalParser (which only contains the ExpressionParser).

How do you best accomplish this in c#, the internal keyword only works on assemblies and private can't be used in namespaces.


回答1:


I wouldn't do this (same opinion as Joe), but here's another solution derived from Lopina's answer: nested classes + partial classes.

PublicClass.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;
            }
        }
    }
}

Program.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();
    }
}

As you can see, your different helper classes are physically separated in different files (maybe it'll help you maintain your code). And you can't access them directly, they are private to the PublicClass.




回答2:


Have you tried using private nested classes?
Take a look in here: Private inner classes in C# - why aren't they used more often?




回答3:


If you're really desperate to do this (in the light of my comment on the original question), you could put all the helper classes into a single assembly and make them internal, so they are effectively closed off from use. Then make a second assembly, the one you let people use, and put the 'public' classes and methods in a second assembly. Then use InternalsVisibleTo to allow your 'public' assembly use the other 'private' assembly's helper classes and methods.

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

This does mean that you have to force people using your library to work in a different assembly to the one containing your 'public' library code. I think from your question you're saying that they are working in the same assembly, in which case you'd have to separate the 'public' library out into a different assembly. And if you did do this, then simply making the methods internal and putting them in the same assembly would do the job after all.

If you go the two-assembly route and if your colleagues are working on the same assembly, at least there's the extra 'step' in referencing another assembly that might prevent them from using it.

And if that isn't enough ... I don't know, write a WCF webservice and work through that*.

*that was satire



来源:https://stackoverflow.com/questions/11540441/how-do-you-make-infrastructure-code-only-visible-in-namespace

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!