1

当 .NET 4.5 发布时,我开始使用 .NET 等出色的属性CallerMemberName。代码更容易理解,开发人员也可以更快地编写代码。它就像一个片段,不仅仅是用于调试/测试目的的功能。

所以我有一个问题。创建和使用这样的东西是否正常?

public class PropertyStore
{
    Dictionary<string, object> data = new Dictionary<string,object>();
    ViewModelBase modelBase;

    internal PropertyStore(ViewModelBase _base)
    {
        modelBase = _base;
    }

    public void SetValue<T>(T value = default(T), [CallerMemberName] string prop = "")
    {
        T prev = GetValue<T>(prop);
        if ((prev == null && value == null) || (prev != null && prev.Equals(value))) return;
        data[prop] = value;
        modelBase.OnPropertyChanged(prop);
    }

    public T GetValue<T>([CallerMemberName] string prop = "")
    {
        if (!data.ContainsKey(prop))
            data[prop] = default(T);
        return (T)data[prop];
    }
}

类助手,使其他类更具可读性,而且我们有我们的属性列表,无需使用反射。用法是:

public class SampleClass : ViewModelBase
{
    PropertyStore PropertyStore;

    public SampleClass ()
    {
        PropertyStore = new PropertyStore(this);
    }

    public string Key
    {
        get { return PropertyStore.GetValue<string>(); }
        set { PropertyStore.SetValue(value); }
    }
    public DateTime Date
    {
        get { return PropertyStore.GetValue<DateTime>(); }
        set { PropertyStore.SetValue(value); }
    }
    public bool IsSelected
    {
        get { return PropertyStore.GetValue<bool>(); }
        set { PropertyStore.SetValue(value); }
    }
}

这里的类ViewModelBase只是实现了INotifyPropertyChanged接口。

据我了解,这种方法类似于 Microsoft Dependency Properties,但我不需要DependencyObject类的所有功能,也不想继承它。有了这样的东西我可以使用Binding,因为它足以实现INotifyPropertyChanged,而且我们没有字段(对于我来说,我尝试使用属性更聪明,而不是直接使用字段(但是,直接使用没有问题Dictionary^_^) )

对不起我的英语不好......不是主要语言,也没有太多练习。

另一个示例(将方法移至基类之后)

public class SampleClass : ViewModelBase
{
    public string Key
    {
        get { return GetValue<string>(); }
        set { SetValue(value); }
    }
    public DateTime Date
    {
        get { return GetValue<DateTime>(); }
        set { SetValue(value); }
    }
    public bool IsSelected
    {
        get { return GetValue<bool>(); }
        set { SetValue(value); }
    }
}

与 Microsoft 的 WPF 属性系统没有区别。

4

2 回答 2

2

您将获得的唯一功能是能够通过 Dictionary.Get|Set 方法访问属性值。

您可以通过基于字段的 INotifyPropertyChanged 实现来获得此功能。您可以使用字典通过其名称访问属性值,使用属性名称到预编译的委托映射,就像在Yappi项目中所做的那样。

var dateValue= Property<SampleClass>.Get<DateTime>(this,"Date");
Property<SampleClass>.Set<DateTime>(this,"Date",DateTime.Now);

两者都可以重写为扩展方法。

于 2013-01-15T09:51:05.337 回答
1

好主意,没有反射的属性包,它甚至可以用于混淆。

我看不出它有什么大问题,但你可以考虑以下几点:

  1. prop 参数是可选的,因此在调用中给定一个值可能会引入错误。
  2. 值类型将被装箱。
  3. 访问这些字段的成本相对较高,可能是一个更昂贵的因素,因为您在简单的获取中拥有更多代码(尤其是使用装箱)。
  4. 字典占用的空间比您保留的属性数量要多(尤其是装箱)。
  5. 每个属性还存储增加开销的属性名称字符串。
于 2013-01-15T08:51:19.900 回答