C# 中的类层次结构:如何正确执行? (想要“朋友”关键字)
我有一堂课:
public class MyClass {
private List<string> folderList;
// .... a lot of useful public methods here.....
}
一切都很好。文件夹列表是封装的,该类可以通过公共方法访问。好的。现在我需要一个“选项”表单,允许用户为 MyClass 选择文件夹。有一个问题:新的安装类必须有权访问私有folderList字段(或者我必须提供公共方法来获取和设置文件夹列表 - 本质上是相同的)。在旧的好的 C++ 中,我会使用“friend”功能,因为除了安装类之外没有人可以访问folderList。但 C# 中没有“朋友”功能(我是 C# 世界的新手)。
PS 其实我只是公开了folderList,但我觉得有更好的解决方案。
谢谢。
I have a class:
public class MyClass {
private List<string> folderList;
// .... a lot of useful public methods here.....
}
Everything is fine. The list of folders is encapsulated, the class is accessible through public methods. OK. Now I need an "options" form that allows a user to choose folders for MyClass. There is a catch: new Setup class must have access to private folderList field (or I have to provide public methods to get and set the folder list - it's essentially the same). In old good C++ I would use 'friend' feature because nobody but Setup class may access folderList. But there is no 'friend' feature in C# (I'm a newbie in the C# world).
P.S. Actually I just made folderList public, but I feel there is a better solution.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您可以使用“internal”关键字使您的方法仅在程序集/项目中可用,如果您想访问其他项目或程序集中的内部方法,则可以使用“InternalsVisibleTo”属性,您只能在该属性中访问内部方法您为其定义此属性的程序集。
MSDN 内部关键字
You can use "internal" keyword to make your method available only within your assembly/project and if you want to access your internal methods in other project or assembly then you can use "InternalsVisibleTo" attribute, where you can access your internals only in that assembly for which you define this attribute.
MSDN Internal Keyword
我相信您正在寻找的关键字是
internal
。它大致相当于 C++ 的friend
。Internal
提供程序集级别的可见性。结合 Femaref 使用属性的建议,您应该拥有完整的解决方案。
I believe the keyword you're looking for is
internal
. It is loosely equivilent to C++'sfriend
.Internal
provides assembly-level visibility.Paired with Femaref's suggestion of using a Property, and you should have your full solution.
我不确定这是否是他/她想要的。他/她没有提出潜在客户将在当前程序集中的要求...因此,在 C++ 中使用
friend
时(这从来不被认为是一种好的风格),您必须知道 有权访问成员的类的确切类型。如果此类不是您正在编写的程序的一部分,则无法以这种方式授予访问权限。如果您想要有条件地访问类实例的某些属性或方法,则需要实现某种权利机制,例如:
我相信 .Net 框架中有内置实用程序用于此目的,只需执行和谷歌(或必应)...
I am not sure if this is what he/she wanted. He/she did not put the requirement that the potential client will be in current assembly... Accordingly, when using
friend
in c++ (which was never considered a good style) you must know the exact type of the class which will be entitled to access the member. If this class is not part of the program you are writing, you cannot grant access this way.If you want conditional access to some property or method of an instance of a class, you will need to implement some kind of entitlement mechanism, for example:
I believe there are built-in utilities in the .Net framwork for that purpose, just go and google (or bing)...
作为问题的确切答案,我建议如下 - 创建一个单独的接口 IFolderList:
好吧,您可以将其他必需的成员添加到接口
中 在类 MyClass 中显式实现此接口。
因此,Setup 类可以通过显式转换为接口 IFolderList 来访问数据,或者仅使用这些接口。
As an exact answer to the question I would suggest the following - create a separate interface IFolderList:
Well, you can add other required members to interface
In the class MyClass implement this interface explicitly.
As a result, the class Setup can gain access to data through an explicit cast to an interface IFolderList or work only with these interface.
使
Setup
类使用internal
方法的另一种方法是使用 Visitor 模式并添加一个采用 Setup 类实例作为参数的方法,然后使用私有folderList
根据需要初始化/更改Setup
状态。当然,这需要Setup
类上的适当公共方法,因此可能不适合您的需求。An alternative to making an
internal
method to be used by yourSetup
class would be to use the Visitor pattern and add a method that takes a Setup class instance as a parameter, then uses the privatefolderList
to initialize/changeSetup
state as required. Of course that would require the appropriate public methods on theSetup
class, so might not fit your needs.将
folderList
字段公开是最坏的情况。通过公共字段或通过设计不良的公共属性暴露实现细节(公共字段和具有 getter 和 setter 的公共属性之间的集合没有区别)。对于公共字段,当您想要添加验证、更改通知、将其放入界面或将集合类型从一种类型更改为另一种类型时,您无法将字段提升为属性。
顺便说一句,Jeffrey Richter 在框架设计指南的注释中提到,“就个人而言,我总是将我的字段设为私有。我什至不将字段公开为内部,因为这样做不会给我任何保护来自我自己的程序集中的代码”
我认为添加向 MyClass 客户端公开严格抽象的显式接口的最佳方法。
例如,您可以添加两个单独的方法来检索文件夹并将新文件夹添加到此存储:
Making
folderList
field public is the worst case. Exposing implementation details through public fields or through poorly designed public property (there are no differences for collections between public fields and public property with getter and setter).With public fields you can't promote a field to be a property when you want to add validation, change notification, put it into an interface or change your collection type from one type to another.
BTW, Jeffrey Richter in annotation to Framework Design Guideline mentioned that "Personally, I always make my fields private. I don't even expose fields as internal, because doing so would give me no protection from code in my own assembly"
I think the best way to add explicit interface that expose strict abstraction to MyClass clients.
For example, you may add two separate methods to retrieving folders and to adding new folder to this storage:
这就是属性在 C# 中的作用:
属性封装私有字段,提供设置时验证的可能性。另外,您应该阅读泛型(有点像 C++ 中的模板)并使用
List
而不是List
来拥有强类型集合。但是,除非
Setup
派生自MyClass
,否则您可能无法实现您的计划。在这种情况下,您可以使用protected
字段。That's what properties are for in C#:
Properties encapsulate the private fields, provide possibilites for validation while setting. Also, you should read up on Generics (abit like templates in c++) and use
List<T>
instead ofList
to have a strongly typed collection.However, you probably wont be able to achieve what you plan unless
Setup
derives fromMyClass
. In that case, you can use aprotected
field.