属性值的容器

时间:2013-01-15 06:48:52

标签: c# .net

当.NET 4.5发布时,我开始使用如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];
    }
}

Class-helper,它使其他类更具可读性,而且我们还有我们的属性列表,而不需要使用Reflection。 用法是:

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 Property System无差别。

2 个答案:

答案 0 :(得分:2)

只有您可以使用它才能通过Dictionary.Get | Set方法访问属性值。

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

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

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

答案 1 :(得分:1)

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

我没有看到它的主要问题,但你可以考虑以下几点:

  1. prop参数是可选的,因此可能通过在调用中给定值来引入错误。
  2. 值类型将被装箱。
  3. 访问这些字段相对更昂贵,因为你在简单的get中有更多的代码(尤其是使用装箱),因此可能会更加昂贵。
  4. 字典比您保留的属性数量占用更多空间(特别是对于拳击)。
  5. 每个属性还存储一个属性名称的字符串,添加到开销中。