2010-01-15 40 views
0

所以我有很多选项,每个不同的页面/选项卡都可以有自己的本地选项。我们可能会有10-15页的标签打开顶部。我需要实现一种显示全局默认值的方法,并且预测所有选项卡具有一致的值。我正在研究WPF应用程序的model/viewmodel部分。作为参数的属性? C#

我很想找到一种更优雅的方式,因为我不得不削减和过去大致相同的代码20+次,只是改变属性名称。也许这是动力学解决的问题,但现在这感觉既错误又痛苦。

这是我目前的解决方案的例子:

public class Foo 
{ 
    private bool fooVar1; 
    private bool fooVar2; 
    //lots of these 
    private decimal fooVar23; 

    public Foo() 
    { 
    } 

    public bool FooVar1 
    { 
     get; 
     set; 
    } 

    //you get the picture... 
} 

public class FooMonitor 
{ 
    private Foo defaultFoo; 
    private List<Foo> allFoos; 

    public FooMonitor(Foo DefaultFoo) 
    { 
     defaultFoo = DefaultFoo; 
    } 

    public void AddFoo(Foo newFoo) 
    { 
     allFoos.Add(newFoo); 
    } 

    public void AddFoo(Foo oldFoo) 
    { 
     allFoos.Remove(oldFoo); 
    } 

    public bool IsFooVar1Consistent 
    { 
     get 
     { 
      Foo[] tempFoos = allFoos.ToArray(); 
      foreach (Foo tempFoo in tempFoos) 
      { 
       if (tempFoo.FooVar1 != defaultFoo.FooVar1) return false; 
      } 
      return true; 
     } 
    } 
} 

还是我完全不正确处理这个问题。 当我写这个问题(大约2000行代码后)我想我是如何阅读WPF自己实现的字典查找爬行到父,看是否存在一个属性和值应该是什么。

回答

2

我很想找到一种方式,是更 优雅,因为我不得不削减和 以往大致相同的代码20+次 ,只是更改属性名称。

代码生成器完全用于此目的。但如果你不想走这条路线,你可以缩短你的代码:

return allFoos.All(foo => foo.FooVar1 == defaultFoo.FooVar1); 
+0

我想这正是我正在寻找的重做整个代码不同的模式。 – 2010-01-15 19:37:33

3

那么,首先你要定义永远不会使用的后台字段和自动属性。这对于简单的bool属性来说是足够的:

public bool FooVar1 { get; set; } 

不需要专用字段。这将大大减少您示例中的行数。

+0

+1教我的东西。 – 2010-01-15 18:47:48

2

我不太清楚的问题是什么,但如果你正在寻找一些方法来统一IsFoorVarXConsistent代码,你可以使用反射或传递在表达它:

public bool IsConsistent(Func<Foo, bool> property) 
{ 
    foreach (Foo tempFoo in allFoos) 
    { 
    if (property(tempFoo) != property(defaultFoo)) 
     return false; 
    } 
    return true; 
} 

这样调用:

bool is1Consistent = IsConsistent(f => f.FooVar1); 

如上所示,这只适用于布尔属性。为了将其扩展到其他类型,我们可以使其在属性类型中是通用的。但是,在这种情况下,我们不能使用!=来测试不等式,因为不是所有的类型都定义了一个!=运算符。相反,我们可以使用.Equals方法和!运营商:

public bool IsConsistent<T>(Func<Foo, T> property) 
    where T : struct 
{ 
    foreach (Foo tempFoo in allFoos) 
    { 
    if (!property(tempFoo).Equals(property(defaultFoo))) 
     return false; 
    } 
    return true; 
} 

where T : struct子句限制该值类型如int,布尔和小数。特别是它不会在字符串上工作。删除where约束允许它在字符串和其他引用类型上工作,但会创建property(tempFoo)为空的可能性,当我们调用.Equals时会导致NullReferenceException。所以如果你删除了值类型约束,那么你将需要为这个场景添加错误处理。

+0

这可以工作,我已经定义了一个==不是值类型的每个对象。 – 2010-01-15 19:38:10