如何在C#中获得更多的封装?

发布于 2024-12-06 14:21:21 字数 455 浏览 1 评论 0原文

我最近大约完全学习了 C#。然而,在 C++ 中,当将对象传递给方法时,我可以使用 const 修饰符实现更好的封装。但在C#中,可以通过引用参数修改对象,例如Graphics对象上的Dispose

有时我需要更多的封装。属性可以给出更好的解决方案。但是,我发现,例如,不允许修改 Form.Location 属性甚至其 X 成员。虽然 Form.Locationget; set; 属性,其成员不能修改。我尝试用 Point {get; 来做到这一点set;} 属性,但我仍然可以修改 X 成员。

正如前面提到的,当诸如 Dispose 之类的方法是对象时,这也是一个问题。

如何在C#中实现更多的封装?

I have recently learned C# fully, approximately. However, in C++ I could implement a better encapsulation when passing objects to methods, with const modifier. But in C#, objects can be modified through the reference parameter, such as Dispose on Graphics object.

I need sometimes more encapsulation. Properties can give a better solution. However, I have found that, for example, the modification to Form.Location property or even to its X member is not allowed. Although Form.Location is get; set; property, its members can not be modified. I tried to do as it with a Point {get; set;} property but I can still modify X member.

This is also an issue when a method for example Disposes an object, as eariler mentioned.

How can I implement more encapsulation in C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

笙痞 2024-12-13 14:21:21

您不能使用 Form.LocationX 属性,因为 Form.Location 是返回值类型的属性()。一旦您访问 Form.Location,您就会获得该位置的副本;因此,更改此副本中的某些内容是没有意义的。由于 this.Location.X = ... 是一个明显的错误,C# 编译器会阻止您这样做。

但是,您可以替换 Form.Location 的完整值,因为它的属性设置器是 public

private void button1_Click(object sender, EventArgs e)
{
    // move window to the left edge of the screen
    this.Location = new Point(0, this.Location.Y);    
}

或者,

private void button1_Click(object sender, EventArgs e)
{
    // move window to the left edge of the screen
    var loc = this.Location;
    loc.X = 0;               // yes, it's a mutable struct
    this.Location = loc;
}

回到您原来的问题:如果您愿意要使对象可访问,但不希望它被修改,您需要自己封装它。例如,如果您希望类的使用者能够在 Graphics 对象上进行 Draw,但不希望他们调用 Dispose,只是无法直接公开 Graphics 对象。相反,您需要包装允许消费者调用的每个方法:

// bad, consumer can do anything with the Graphics object
public Graphics Graphics
{
    get { return graphics; }
}

// good, consumer can only do specific stuff
public void Draw(...)
{
    graphics.Draw(...);
}

You cannot the X property of Form.Location, because Form.Location is a property that returns a value type (Point). As soon as you access Form.Location, you get a copy of the location; thus, changing something in this copy is meaningless. Since this.Location.X = ... is an obvious mistake, the C# compiler prevents you from doing it.

You can, however, replace the complete value of Form.Location, since its property setter is public:

private void button1_Click(object sender, EventArgs e)
{
    // move window to the left edge of the screen
    this.Location = new Point(0, this.Location.Y);    
}

or, alternatively,

private void button1_Click(object sender, EventArgs e)
{
    // move window to the left edge of the screen
    var loc = this.Location;
    loc.X = 0;               // yes, it's a mutable struct
    this.Location = loc;
}

To get back to your original question: If you want to make an object accessible, but do not want it to be modified, you will need to encapsulate it yourself. For example, if you want the consumers of your class to be able to Draw on your Graphics object but do not want them to call Dispose, just cannot expose the Graphics object directly. Instead, you need to wrap every method that the consumer is allowed to call:

// bad, consumer can do anything with the Graphics object
public Graphics Graphics
{
    get { return graphics; }
}

// good, consumer can only do specific stuff
public void Draw(...)
{
    graphics.Draw(...);
}
复古式 2024-12-13 14:21:21

这里有两篇文章讨论了为什么 C# 中没有“const”修饰符:

http://blogs.msdn.com/b/ericgu/archive/2004/04/22/118238.aspx

http://blogs.msdn.com/b/slippman/archive /2004/01/22/61712.aspx

将类设计为 immutable 有时可以解决您的问题,但并不总是一个选项,因为它只适用于“类”级别,而不是方法级别。有时您可能必须公开类的成员变量,该变量不是不可变类型,因此可以从外部修改。

最佳选择:接受这一点,在实践中,常量的重要性常常被高估。

Here are two articles discussing why there is no "const" modifier in C#:

http://blogs.msdn.com/b/ericgu/archive/2004/04/22/118238.aspx

http://blogs.msdn.com/b/slippman/archive/2004/01/22/61712.aspx

Designing classes as immutable is sometimes a solution to your problem, but is not always an option, since it does only work on the "class" level, not on the method level. And sometimes you may have to expose a member variable of your class which is not of an immutable type and could therefore be modified from outside.

Best option: live with that, in practice the importance of const-ness is often overrated.

千纸鹤带着心事 2024-12-13 14:21:21

你需要 Point { get; }。这是允许修改的set

You need Point { get; }. It's the set that allows modification.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文