Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#限制类的使用_C#_Design Patterns_Architecture - Fatal编程技术网

C#限制类的使用

C#限制类的使用,c#,design-patterns,architecture,C#,Design Patterns,Architecture,下面的代码就是我希望它做的。Main方法中的代码的外观和行为完全符合要求。但是,如果类UserMenu、Home和DropdownMenu2只能由HeaderVigationMenu使用,以保护其他开发人员不尝试在HeaderVigationMenu类之外使用它们,则更可取。此外,大多数文章都不赞成把一切公之于众 问题: 下面使用的设计模式是否合适,或者在这种情况下是否有更好、更可接受的方法 编辑:此设计的原因 我希望HeaderNavigationMenu的最终用户能够使用点符号来获得可用选

下面的代码就是我希望它做的。Main方法中的代码的外观和行为完全符合要求。但是,如果类UserMenu、Home和DropdownMenu2只能由HeaderVigationMenu使用,以保护其他开发人员不尝试在HeaderVigationMenu类之外使用它们,则更可取。此外,大多数文章都不赞成把一切公之于众

问题: 下面使用的设计模式是否合适,或者在这种情况下是否有更好、更可接受的方法


编辑:此设计的原因

  • 我希望HeaderNavigationMenu的最终用户能够使用点符号来获得可用选项的列表。此体系结构实现了此目标(例如:navigationMenu.DropdownMenu2.SelectOption3())
  • 希望最终可能需要编辑代码的任何其他人能够理解UserMenu、Home和DropDownMenu2类,这些类是专门设计由HeaderVigationMenu类实现的


  • 限制对类构造函数的访问。如果它们被声明为“内部”然后,类可能只能由您的代码创建。

    我不太了解您的用例是什么,我从来没有这样编写过代码,但只公开
    HeaderNavigationMenu
    所需行为的一种方法是将类设为内部类,并将变量设为私有类,然后只公开
    SelectOption3()
    方法,如下所示

    如果您取消对该行的注释

    //Home home = new Home();
    
    您将得到一个编译器错误

    class Program
    {
        static void Main(string[] args)
        {
            HeaderNavigationMenu navigationMenu = new HeaderNavigationMenu();
            navigationMenu.DropdownMenu2SelectOption3();
    
            // The following code is an example of undesired capability; 
            // prefer if Home class could only be 
            // used by HeaderNavigationMenu class
            //Home home = new Home();
        }
    }
    public class HeaderNavigationMenu
    {
        UsersMenu usersMenu;
        Home home;
        DropdownMenu2 dropdownMenu2;
    
        public HeaderNavigationMenu()
        {
            usersMenu = new UsersMenu();
            home = new Home();
            dropdownMenu2 = new DropdownMenu2();
        }
    
        public void DropdownMenu2SelectOption3()
        {
            dropdownMenu2.SelectOption3();
        }
    
        class UsersMenu
        {
        }
    
        class Home
        {
        }
    
        class DropdownMenu2
        {
            public void SelectOption3()
            {
            }
        }
    }
    

    您可以创建
    用户菜单
    主页
    ,以及
    下拉菜单2
    公共摘要
    类。然后在
    HeaderNavigationMenu
    中嵌套
    private
    类,这些类扩展了
    public abstract
    版本

    公共抽象类用户菜单
    {
    }
    公共抽象类主页
    {
    }
    公共抽象类下拉菜单2
    {
    public void SelectOption3()
    {
    //选择选项3的代码。。。
    }
    }
    公共类标题激活菜单
    {
    公共标题激活菜单()
    {
    UsersMenu=新的UsersMenuImpl();
    Home=新的HomeImpl();
    DropdownMenu2=新的DropDownMenuImpl();
    }
    公共用户菜单用户菜单{get;}
    公共住宅{get;}
    公共下拉菜单2下拉菜单2{get;}
    私有类UsersMenuImpl:UsersMenu
    {
    }
    私有类HomeImpl:Home
    {
    }
    私有类DropDownMenuImpl:DropdownMenu2
    {
    }
    }
    
    其他开发人员可以查看和使用
    用户菜单
    主页
    、和
    下拉菜单2
    抽象
    类,但不能创建它们的实例。只有
    headernavigation菜单


    当然,另一个开发人员总是可以从
    公共抽象
    类派生出他们自己的类,但是你能做的只有这么多
    UsersMenu
    Home
    DropdownMenu2
    必须是
    public
    ,才能成为
    public
    属性。

    如果您希望防止
    UsersMenu
    的实例化,
    DropdownMenu2
    ,和
    Home
    从外部
    HeaderNavigationMenu
    但仍在与
    HeaderNavigationMenu
    相同的项目中,那么有一个巧妙的技巧可以实现这种行为。可以将公共嵌套类与私有构造函数一起使用,私有构造函数静态初始化它们自己的工厂方法。这方面的基本模板是:

    公共类外部{
    私有静态函数内部工厂;
    公共内部公开器{get;private set;}
    公共图书馆{
    //强制运行静态初始值设定项。
    System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(内部).TypeHandle);
    //调用新创建的工厂方法,而不是常规构造函数。
    ExposedInner=_innerFactory();
    }
    公共阶级内部{
    静态内部(){
    //初始化外部的静态工厂方法。
    _innerFactory=()=>新内部();
    }
    //内部无法实例化(无反射),因为其构造函数是私有的。
    私有内部(){}
    //此方法现在公开给任何人使用。
    public void DoStuff(){Console.WriteLine(“Did stuff”);}
    }
    }
    
    在您的示例中实现了以下概念:

    类程序
    {
    静态void Main(字符串[]参数)
    {
    HeaderNavigationMenu导航菜单=新建HeaderNavigationMenu();
    导航菜单。下拉菜单2。选择选项3();
    //此行将不再工作,因为构造函数
    //因为内部类是私有的。
    HeaderNavigationMenu.homeempl home=新建HeaderNavigationMenu.homeempl();
    Console.ReadKey();
    }
    }
    公共类标题激活菜单
    {
    //静态初始化的私有工厂方法
    私有静态函数创建用户;
    私有静态函数创建下拉列表;
    私有静态函数_createHome;
    公共标题激活菜单()
    {
    //强制静态构造函数运行
    System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(UsersMenuImpl.TypeHandle);
    System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(HomeImpl.TypeHandle));
    System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(DropDownMenuImpl.TypeHandle);
    UsersMenu=_createUsers();
    主页=_createHome();
    DropdownMenu2=_createDropdown();
    }
    public UsersMenuImpl UsersMenu{get;set;}
    公共HomeImpl Home{get;set;}
    公共DropdownMenu2Impl DropdownMenu2{get;set;}
    公共类UsersMinImpl
    {
    //创建类工厂方法的静态构造函数
    静态UsersMenuImpl()
    {
    _createUsers=()=>new UsersMinImpl();
    }
    私有用户smenuimpl(){}
    }
    公共类HomeImpl
    
    class Program
    {
        static void Main(string[] args)
        {
            HeaderNavigationMenu navigationMenu = new HeaderNavigationMenu();
            navigationMenu.DropdownMenu2SelectOption3();
    
            // The following code is an example of undesired capability; 
            // prefer if Home class could only be 
            // used by HeaderNavigationMenu class
            //Home home = new Home();
        }
    }
    public class HeaderNavigationMenu
    {
        UsersMenu usersMenu;
        Home home;
        DropdownMenu2 dropdownMenu2;
    
        public HeaderNavigationMenu()
        {
            usersMenu = new UsersMenu();
            home = new Home();
            dropdownMenu2 = new DropdownMenu2();
        }
    
        public void DropdownMenu2SelectOption3()
        {
            dropdownMenu2.SelectOption3();
        }
    
        class UsersMenu
        {
        }
    
        class Home
        {
        }
    
        class DropdownMenu2
        {
            public void SelectOption3()
            {
            }
        }
    }