【问题标题】:Is it possible to know when a object property has changed?是否可以知道对象属性何时更改?
【发布时间】:2013-10-10 00:28:51
【问题描述】:

我需要控制结构或对象属性何时更改。它没有任何我可以使用的事件。

示例:我如何知道宽度或高度何时更改?这可能吗?

"System.Drawing.Size = 尺寸"

    private Size mySize;

    public Size MySize
    {
        get {
            //What if X or Y is changed?? I need to know that
            return mySize; 
        }
        set {

            mySize = value; 
        }
    }

对于这种特定情况,如果 Size 属性是只读的,则问题将得到解决。但他们不是。

【问题讨论】:

  • 您可以在那里创建自己的活动。 .NET 有一个 OnPropertyChanged 事件,您可以将其用作基础。
  • 大小是你的班级还是来自框架?
  • 您可能需要使用PropertyChangedEventHandler
  • @cadrell0,Size 是来自 .NET 的结构
  • @GarrisonNeely,是的,我知道。但是 Size 是一个结构,它没有属性更改事件。因此,如果有人更改了 Width 或 Height,我的班级将不会意识到这一点。

标签: c# properties


【解决方案1】:

编辑以响应 cmets:

示例:我如何知道宽度或高度何时更改?这可能吗?

不,这是不可能的。不过没关系。

当您从班级返回Size 时,由于Size is a struct,您返回的是副本。即使用户更改了您返回的SizeWidthHeight,也不会影响您类中的mySize 结构。

为了改变你的尺寸,他们需要改变整个事情,即:

var temp = yourClass.MySize;
temp.Width = newWidth;
yourClass.MySize = temp; // The user will need to assign an entire Size

就您而言,Size 属性实际上是只读的,因为System.Drawing.Size 是一个值类型。


原始答案,假设 Width 和 Height 是用户类的属性:

有两个主要选项 -

您可以根据您的宽度和高度即时计算尺寸,而不是存储它:

public Size MySize
{
    get {            
        return new Size(Width,Height); 
    }
    set {
        Width = value.Width; 
        Height = value.Height; // Set Width/Height appropriately
    }
}

另一种选择是在属性设置器中重新计算宽度和高度的尺寸:

public double Width
{
   get { return width; }
   set
   {
         width = value;
         mySize = new Size(width, Height); // Compute new size, so it's always correct
   }
}

最后,如果您使用 INotifyPropertyChanged 之类的东西来跟踪更改,您还可以订阅自己的 PropertyChanged 事件,如果它是适当的属性,请重新计算您的大小。

【讨论】:

  • 如果有人更改 Width 或 Height,我的班级将不会意识到这一点。这就是问题所在。
  • @Pedro77 宽度和高度也属于您的课程吗?如果是这样,只需将它们设为属性,它们改变它的唯一方法就是让你意识到它......
  • 不,它们是 .NET Size 结构的一部分。
  • @Pedro77 用户不能直接在你的尺寸上设置宽度和高度 - 尺寸是一个结构,这意味着你的属性返回一个 copy - 所以他们没有办法可以改变宽度和高度。
【解决方案2】:

简短的回答 - 不,在字段更改时触发的普通旧 C# 对象上没有事件。

我知道的你的选择:

  • 更改您的课程(如果可以的话)以触发事件
  • 从您的类继承并在派生类中编写事件触发代码(假设可以进行虚拟获取/设置)
  • 将属性提取到接口中,在整个代码中使用该接口,并为触发属性更改的通用接口构建包装器。

请注意mutable struct considered evil - 尽量避免“每当struct 属性发生更改时”的情况。

【讨论】:

  • 解决方案是创建一个新的 Size 类,例如实现属性更改事件的“class MySize”。不可能使用旧的 Size 结构,因为 Width 或 Height 可以在我的班级之外更改。我希望有解决该问题的方法。
【解决方案3】:

您可以创建一个事件并在适当的 Set 方法中引发它。或者,您可以查看此链接,有两个示例:

Raise an event whenever a property's value changed?

【讨论】:

    【解决方案4】:

    意识到它是一个结构后编辑:

    考虑一下 Eric Lippert 在他的博客中关于可变结构的精彩文章 Mutating Readonly Structs(Evil)

    看看INotifyPropertyChanged Interface

    INotifyPropertyChanging Interface

    【讨论】:

    • 是的,我知道。但是 Size 是一个结构,它没有实现这个接口。因此,如果有人更改了 Width 或 Height,我的班级将不会意识到这一点。
    • 框架本身不提供这样的选项,你必须实现一个。
    猜你喜欢
    • 2016-06-24
    • 2019-10-28
    • 2021-12-02
    • 1970-01-01
    • 2018-05-15
    • 2022-07-01
    • 2015-01-28
    • 1970-01-01
    • 2015-05-17
    相关资源
    最近更新 更多