如何动态设置属性setter方法

本文关键字:设置 属性 setter 方法 动态 何动态 | 更新日期: 2023-09-27 17:59:29

我一直在四处搜索,但似乎找不到我要找的东西,所以我在这里试试。

情况:我有MainWindow和MainWindowData类。在MainWindowData中,只有使用属性UpdateGUI定义的公共属性。

public class UpdateGUI : Attribute { }
public class MainWindowData
{
    [UpdateGUI]
    public string TESTVAR { get; set; }
}

现在,我想在MainWindowData中为每个属性的setter方法添加一个方法。更具体的:

void OnPropertyChanged(String PropertyName);

我想我会在MainWindow构造函数中获取所有UpdateGUI属性,然后以某种方式向其中添加另一个方法,但这就是我的问题所在。我使用这段代码来获取所有属性,这很有效:

List<PropertyInfo> properties = (from pi in typeof(MainWindowData).GetProperties()
                                 where pi.GetCustomAttributes(typeof(UpdateGUI), false).Any()
                                 select pi).ToList();

这给了我一个很好的列表,列出了我必须更新的所有属性。

所以问题是:我如何才能使属性从动态转换

[UpdateGUI]
public string TESTVAR { get; set; }

至:

[UpdateGUI]
private string _TESTVAR;
public string TESTVAR { 
    get {
        return _TESTVAR;
    }
    set {
        _TESTVAR = value;
        OnPropertyChanged("TESTVAR");
    }
}

谢谢你的帮助!非常感谢:)

问候

如何动态设置属性setter方法

您正在寻找的问题已经在面向方面编程(AOP)的概念中得到了解决。

一个例子是在PostSharp中(另外,请参阅此处的详细信息),它可以让您像这样编写数据/视图模型类:

[NotifyPropertyChanged]
public class Shape
{
    public double X { get; set; }
    public double Y { get; set; }
}
public class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }
}

如果你不喜欢PostSharp,我相信其他AOP框架也有类似的功能。

编辑

我刚刚找到了NotifyPropertyWeaver,它为您做到了这一点,而不需要完整的AOP框架。

它使用Mono.Cecil的东西在编译期间注入通知代码,并且可以通过NuGet(我就是这么做的)或从项目网站安装。

默认情况下,它甚至不需要属性(它会自动计算出哪些属性和类需要更改通知),但你也可以显式,比如:

[NotifyProperty]
public int FooBar { get; set; }

我在其中发现的一个很好的特性是可以声明属性之间的依赖关系。在这种情况下,只要FooBar发生更改,就会调用RaisePropertyChanged("FoobarTimesTwo")

[DependsOn("FooBar")]
public int FoobarTimesTwo
{
    get { return FooBar * 2; }
}

除了PostSharp这样的AOP框架之外,还有以下内容:

Mono.Cecil

使用该工具,您可以获取一个程序集,修改其代码并将其保存回

林福有一些关于AOP的文章可能对有所帮助

林福关于CodeProject 的文章

开源框架ImpromptuInterface.MVVM使用C#4.0动态特性添加支持属性更改的自动属性。它的ImpromptuViewModel与ExpandoObject类似,但也有其他功能可以帮助MVVM。