限制类方法访问另一个类

时间:2010-11-13 01:37:41

标签: c# access-modifiers restriction

问候。

我有两个类,'数据库'和'组'。我希望能够在“数据库”中创建“组”实例并在这些实例上调用方法,并能够公开分发“组”实例引用。但是,我不想公开访问“Group”中的构造函数或其他方法。

我原本以为我可以通过使'Group'成为'Database'的私有内部类来实现这种访问限制,但我发现如果它是私有的,我不能公开分发对'Group'的引用。此外,我将'Group'设为公共内部类的尝试失败了,因为如果它的方法都是私有的,'Database'无法访问它们,如果它们是公共的,那么访问可能超出'Database'。

我正在寻找解决或避免此问题的最佳实践技巧。也许我错过了某个必要的关键字?到目前为止,我在研究中发现的任何内容都表明C#允许这种控制粒度。我找到了解决问题的混乱方法,正如我在下面的代码中提供的那样。它的本质是这样的:在“数据库”中每次调用“组”中的方法之前,在“数据库”中设置一个字段,可以公开读取,但只能私下设置,“组”的方法都会检查它们的创建实例'数据库'在执行预期的操作之前。当读取字段时(通过“数据库”中的公共方法),字段将被重置,防止对“组”进行任何进一步的方法调用,直到“数据库”再次设置字段为止。

public class Database {

    // Field; true if Database has just authorized a method call to a %Group.
    private bool group_isNextCallAuthorized = false;

    // Invoked before every method call to a %Group.
    private void Group_AuthorizeNextCall() {
        group_isNextCallAuthorized = true;
 }

    // Method, ordinarily called from %Group, that checks its creating %Database
    //  that the %Database itself authorized the method call on the %Group. It
    //  automatically resets the authorization to false to prepare for the next,
    //  perhaps unauthorized, method call.
    public bool Group_IsNextCallAuthorized() {
        bool previousValue = group_isNextCallAuthorized;
        group_isNextCallAuthorized = false;
        return previousValue;
    }

    // Constructor; creates a demo %Group.
    public Database() {

        // Create a %Group, first authorizing the action.
        Group_AuthorizeNextCall();
        Group group = Group.Create(this);

        // Call some method on the group
        Group_AuthorizeNextCall();
        group.SomeGroupMethod();

    }

}

public class Group {

    // Field; refers to the %Database that created this %Group instance.
    private Database db;

    // Generates an instance of %Group, requiring the creating %Database as an
    //  argument. After checking that the %Database %db isn't null, it verifies
    //  that %db actually requests and authorized this %Group's creation via the
    //  %Group_IsNextCallAuthorized(.) method provided by %Database.
    public static Group Create(Database db) {

        // It will not create a dud instance of %Group; it will throw an exception
        //  instead.
        if ((db == null) || !db.Group_IsNextCallAuthorized())
            throw new System.Exception("Unauthorized access.");

        return new Group(db);
    }

    // This constructor is referenced internally by static %Create(.) as above.
    private Group(Database db) {
        this.db = db;
    }

    // This is an arbitrary method showing that it must check that the %Database
    //  that created this %Group authorized this method call before it will
    //  perform its intended function.
    public void SomeGroupMethod() {
        if (!db.Group_IsNextCallAuthorized())
            throw new System.Exception("Unauthorized access.");

        // intended functionality...
    }

}

3 个答案:

答案 0 :(得分:5)

一种选择是将接口IGroup暴露给代码的外部部分。这个接口只有属性上的getter,你想要访问的方法等等。然后Database将在Group类上运行,拥有对所有属性/方法的完全访问权限,并返回IGroup

答案 1 :(得分:3)

您可以使用嵌套类方法。可能不是最优雅的,因为紧密耦合,但会做到这一点。

 public class DataBase 
 {
      private class Group 
      {
            private Group() {} 

      }

      private Group group = null;

      public DataBase() 
      {
         this.group = new Group();
      }

      public Group 
      {
         get 
         {
            return this.group;

         }   
 }

答案 2 :(得分:0)

要使用C#访问规则表达此可见性,您需要反转类嵌套:使数据库成为Group中的嵌套类,以便它可以访问Group的私有位。