问候。
我有两个类,'数据库'和'组'。我希望能够在“数据库”中创建“组”实例并在这些实例上调用方法,并能够公开分发“组”实例引用。但是,我不想公开访问“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...
}
}
答案 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的私有位。