[英]C#, making public members their methods private
我是以下课程:
public class Humptydump
{
public Humptydump()
{ }
public Rectangle Rectangle { public get; private set; }
}
在这个类中,Rectangle类来自system.drawing,
我怎么做它所以人们无法访问矩形的方法,但可以得到矩形本身?
在你的情况下,它将“正常工作”。
由于Rectangle
是一个struct
,因此您的属性将返回Rectangle
的副本 。 因此,任何人都不可能直接修改Rectangle
,除非您公开允许这样做的方法。
话虽这么说,一般来说,提供对类型的访问是不可能的,而不提供对类型上定义的方法的访问。 方法与类型一致。 在这些情况下,唯一的选择是创建一个新类型,在没有您希望公开的数据或方法的情况下公开您选择的数据,并提供对它的访问。
如果矩形不是结构,那么可能会导出它并隐藏这些方法:
public class DerivedClass : BaseClass
{
new private SomeReturnType SomeMethodFromBaseClasse(SameParametersAsInBaseClassAndSameSignature
{
//this simply hides the method from the user
//but user will still have the chance to cast to the BaseClass and
//access the methods from there
}
}
你是在具体谈论Rectangle
对象,还是在一个更通用的术语上,只是以它为例?
如果你正在谈论一个更通用的术语,那么在重构模式中经常会出现这种情况。 这通常发生在对象上的集合中。 例如,如果您公开List<T>
那么即使setter是私有的,人们仍然可以通过getter修改集合,因为他们实际上并没有设置集合。
要解决这个问题,请考虑德米特定律 。 也就是说,当某人与一个对象暴露的集合进行交互时,他们是否真的要与对象本身进行交互? 如果是这样,那么不应该公开该集合,而是该对象应该公开它需要的功能。
所以,再一次在集合的情况下,你最终会得到这样的东西:
class SomeObject
{
private List<AnotherObject> Things;
public void AddAnotherObject(AnotherObject obj)
{
// Add it to the list
}
public void RemoveAnotherObject(AnotherObject obj)
{
// Remove it from the list
}
}
当然,您可能还希望公开对象本身的一些副本供人们阅读,但不能修改。 对于一个集合,我可能会这样做:
public IEnumerable<AnotherObject> TheObjects
{
get { return Things; }
}
这样任何人都可以看到对象的当前状态并枚举它们,但它们实际上无法修改它。 不是因为它没有setter,而是因为IEnumerable<T>
接口没有修改枚举的选项。 只能枚举它。
对于使用Rectangle
的情况(或类似的东西, Rectangle
不是一个通过值传递的结构),你会做一些非常相似的事情。 存储私有对象并提供公共功能以通过类本身对其进行修改(因为我们所讨论的是类需要知道其成员何时被修改)以及检查它的功能而无法修改正在进行的操作检查。 也许是这样的事情:
class SomeObject
{
private AnotherObject Thing;
public AnotherObject TheThing
{
get { return Thing.Copy(); }
}
public void RenameThing(string name)
{
Thing.Name = name;
}
// etc.
}
在这种情况下,没有详细讨论AnotherObject
是什么(所以在某些方面考虑伪代码),检查内部对象的属性返回它的副本,而不是实际对象的实际引用。 对于值类型,这是该语言的默认行为。 对于参考类型,您可能需要在此与性能之间取得平衡(如果创建副本是繁重的操作)。
在这种情况下,您还需要小心使对象的界面不直观。 使用代码可能希望能够修改被检查的内部对象,因为它公开了修改自身的功能。 事实上,他们可以修改他们拥有的副本。 你如何解决这个问题在很大程度上取决于对象的概念性质以及它们之间的相互关系,这是一个人为的例子并没有真正传达出来的。 您可以创建一个自定义DTO(甚至是一个结构),它只返回内部对象的可观察属性,这使得它更复杂,而不是原始对象。 您可能只是说它是intellisense评论中的副本。 您可以创建单独的属性以返回内部对象的单个数据元素而不是单个属性以返回对象本身。 有很多选项,由您决定什么对您的对象最有意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.