3

问候。

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

我最初认为我可以通过将“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...
    }

}
4

3 回答 3

5

一种选择是将接口 IGroup 暴露给代码的外部部分。这个接口只有属性的getter,你想要访问的任何方法等。然后数据库将对Group类进行操作,完全访问所有属性/方法,并返回IGroup

于 2010-11-13T01:44:58.697 回答
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;

         }   
 }
于 2010-11-13T02:01:45.930 回答
0

要使用 C# 访问规则表达这种可见性,您需要反转类嵌套:使 Database 成为 Group 内的嵌套类,以便它可以访问 Group 的私有位。

于 2010-11-13T02:24:45.713 回答