C# - 截获子类中的属性更改
本文关键字:属性 子类 | 更新日期: 2023-09-27 17:57:02
我正在创建一个框架,其中我提供了基类,框架的实现者将从基类继承并提供其他属性和方法。 在基类中,我想有一种观察属性值何时更改的方法。 该属性可以来自基类,也可以位于任何子类中。 我知道通过反射,我可以确定任何实例的属性列表,但是有没有办法跟踪属性更改值?
以下是我所说的一个非常简单的例子:
public class BaseClass
{
public string BaseClassProperty { get; set; }
public void DoSomethingWhenEitherPropertyGetsChanged()
{
}
}
public class SubClass : BaseClass
{
public string SubClassProperty { get; set; }
}
当任何一个属性的值发生变化时,我该怎么做才能DoSomethingWhenEitherPropertyGetsChanged
执行。
notifypropertyweaver
来实现此目的。 它完全符合您的要求。 这是一个链接:
- 通知财产编织者
从开源主页:
使用 IL 编织(通过 http://www.mono-project.com/Cecil)将 INotifyPropertyChanged 代码注入到属性中。
- 无需属性
- 无需参考资料
- 无需基类 支持 .net 3.5、.net 4、Silverlight 3、Silverlight
- 4、Silverlight 5 和 Windows Phone 7
- 支持客户端配置文件模式
我可能会使用 Postsharp 并创建一个继承的属性,将拦截代码注入所有公共属性。将属性标记为继承也应自动将其附加到所有子类。
我写了我自己对您的要求的想法,但我不确定它是否适合您的需求。INotify属性更改是你也可以研究的东西,但我真的不喜欢它,因为它就像连接speghetti一样。不过,也许这会给你一些创造性的想法。
这样做的作用是允许您对所有属性类型使用 ObservableObject。通过执行此操作,每个属性都将有一个可以连接到的 ObjectChanged 事件。缺点是必须初始化构造函数中的所有属性,以防止代码中某处出现 NullReferenceException。
此示例使用三个类。
- 可观察对象.cs
- 员工.cs
- 程序.cs
可观察对象.cs
//-----------------------------------------------------------------------------
// <copyright file="ObservableObject.cs" company="DCOM Productions">
// Copyright (c) DCOM Productions. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------
namespace PropertyChangedEventExample {
using System;
public class ObservableObject : Object {
/// <summary>
/// Expose the default constructor
/// </summary>
public ObservableObject() {
// No default implementation
}
private object m_Object = null;
/// <summary>
/// Base object
/// </summary>
public object Object {
get {
return m_Object;
}
set {
if (m_Object != value) {
m_Object = value;
OnObjectChanged(this, EventArgs.Empty);
}
}
}
/// <summary>
/// Triggered when the value of this object has changed.
/// </summary>
public event System.EventHandler<EventArgs> ObjectChanged;
/// <summary>
/// EventHandler wire-up
/// </summary>
protected virtual void OnObjectChanged(object sender, System.EventArgs e) {
if (ObjectChanged != null) {
ObjectChanged(sender, e);
}
}
/// <summary>
/// Gets the value
/// </summary>
public object Get() {
return this.Object;
}
/// <summary>
/// Sets the value
/// </summary>
public void Set(object value) {
this.Object = value;
}
}
}
员工.cs
//-----------------------------------------------------------------------------
// <copyright file="Employee.cs" company="DCOM Productions">
// Copyright (c) DCOM Productions. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------
namespace PropertyChangedEventExample {
using System;
public class Employee {
/// <summary>
/// Expose default constructor
/// </summary>
public Employee() {
Name = new ObservableObject();
}
/// <summary>
/// Gets or sets the name
/// </summary>
public ObservableObject Name {
get;
set;
}
}
}
程序.cs
//-----------------------------------------------------------------------------
// <copyright file="Program.cs" company="DCOM Productions">
// Copyright (c) DCOM Productions. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------
namespace PropertyChangedEventExample {
using System;
class Program {
static void Main(string[] args) {
Employee employee = new Employee();
employee.Name.Set("David");
employee.Name.ObjectChanged += new EventHandler<EventArgs>(Name_ObjectChanged);
employee.Name.Set("Dave");
Console.ReadKey(true);
}
static void Name_ObjectChanged(object sender, EventArgs e) {
ObservableObject employee = sender as ObservableObject;
Console.WriteLine("Name changed to {0}", employee.Get());
}
}
}
最好的选择是CrisWue推荐的,并使用postsharp或其他一些后处理器将行为注入到您的属性中。除此之外,我认为您需要在您的属性中手动调用 DoSomethingWhenBothPropertyGetsChanged()。
如果要创建由您或您的组织以外的人员使用的库,则后处理器可能不是正确的方法,因为它将第三方工具作为另一个要求添加到其构建过程中。