开发者

How to get more encapsulation in C#?

开发者 https://www.devze.com 2023-04-07 13:09 出处:网络
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 throu

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 Di开发者_高级运维sposes an object, as eariler mentioned.

How can I implement more encapsulation in C#?


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(...);
}


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.


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

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号