简体   繁体   English

C#属性问题

[英]C# properties issue

The other day I bumped into a little problem regarding C#'s properties. 前几天我碰到了一些关于C#属性的问题。

Let's say I have this setup: 假设我有这个设置:

public class Point
{
 public float X;
 public float Y;
}

public class Control
{
 protected Point m_Position = new Point();

 public Point Position
 {
  get { return m_Position; }
  set 
  { 
    m_Position = value; }
    // reorganize internal structure..
    reorganize();
  }

  protected reorganize()
  {
   // do some stuff
  }
}

This is all fine, but when it comes to usage, I could write something like: 这一切都很好,但在使用方面,我可以这样写:

Control myControl = new Control();
myControl.Position.X = 1.0f;

The thing is, my Control class won't recognize that the Position has been changed because set() hasn't been called. 问题是,我的Control类将无法识别Position已被更改,因为尚未调用set()

Is there a way to make Control aware of any Position changes? 有没有办法让Control知道任何Position变化?

There are a number of options in this case: 在这种情况下有很多选择:

  1. Make the X and Y properties of your Point class immutable. 使Point类的X和Y属性不可变。 That is, require the user to create a new Point whenever X or Y changes. 也就是说,只要X或Y发生变化,就要求用户创建一个新的Point。
  2. Setup an event on the Point class and subscribe to it on the Position class. 在Point类上设置一个事件,并在Position类上订阅它。 Whenever the Point's X or Y changes, fire the event. 每当Point的X或Y改变时,触发事件。 The Position class can handle side-effects in the event handler. Position类可以处理事件处理程序中的副作用。

In this case, I would suggest option #1 在这种情况下,我会建议选项#1

The statement myControl.Position.X = 1.0f; 语句myControl.Position.X = 1.0f; actually calls the getter and not the setter of your Position property. 实际上调用getter而不是Position属性的setter。 A way to do what you want to do could be by exposing the X and Y values directly on your class, like so: 一种做你想做的事情的方法可以是直接在你的类上暴露X和Y值,如下所示:

public class Control  
{  
 protected Point m_Position = new Point();  

 public float PositionX
 {  
  get { return m_Position.X; }  
  set   
  {   
    m_Position.X = value; }  
    // reorganize internal structure..  
    reorganize();  
  }  

  ... Same thing for PositionY

  protected reorganize()  
  {  
   // do some stuff  
  }  
}

Another way would be to implement some event on the Position class that is raised every time X or Y change. 另一种方法是在每次X或Y更改时引发的Position类上实现一些事件。 This would entail making X and Y into properties on the Point object, and raising an event each time they are changed. 这将使得X和Y成为Point对象的属性,并在每次更改时引发事件。 Your control would then have to subscribe to that event. 然后,您的控件必须订阅该事件。

1) Make Point.X and Point.Y private. 1)使Point.X和Point.Y私有。 2) Add properties for X and Y to Point. 2)将X和Y的属性添加到Point。 3) Add an event to Point that is raised when either X or Y are modified. 3)向修改X或Y时引发的Point添加事件。 4) Register Control as a listener for the events that are raised by Point. 4)注册Control作为Point引发的事件的监听器。

You could make public class Point a public struct Point . 你可以使public class Point成为一个public struct Point This way, the compiler will force you to write 这样,编译器会强制你写

myControl.Position = new Point() { X = 1.0f, Y = myControl.Position.Y; }

and the property setter is called. 并调用属性setter。

This should fix it! 这应该解决它! I have added a line into your getter that tests to see if the point is null and if it is instantiate it before returning. 我在你的getter中添加了一行,用于测试该点是否为null以及它是否在返回之前实例化它。

public class Point
{
 public float X;
 public float Y;
}

public class Control
{
 protected Point m_Position = new Point();

 public Point Position
 {
  get 
  { 
      if (m_Position == null) m_Position = new Point();
      return m_Position; 
  }
  set 
  { 
    m_Position = value; 
    // reorganize internal structure..
    reorganize();
  }

  }

  protected reorganize()
  {
   // do some stuff
  }
}

HTH HTH

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM