属性作为参数? C#

时间:2010-01-15 18:38:05

标签: c# .net wpf properties

所以我有很多选项,每个不同的页面/标签都可以有自己的本地选项。我们可能有10-15页的标签打开顶部。我需要实现一种显示全局默认值的方法,所有选项卡都具有一致的值。我正在研究WPF应用程序的模型/ viewmodel部分。

我很想找到一种更优雅的方式,因为我不得不切割和过去大致相同的代码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本身实现的字典查找,爬行到父级以查看属性是否存在以及值应该是什么。

3 个答案:

答案 0 :(得分:3)

嗯,首先,您要定义永远不会使用的支持字段和自动属性。这对于简单的bool属性来说就足够了:

public bool FooVar1 { get; set; }

不需要私人领域。这大大减少了示例中的行数。

答案 1 :(得分: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,bool和decimal。特别是它不适用于字符串。删除where约束允许它处理字符串和其他引用类型,但是会创建property(tempFoo)为空的可能性,当我们在其上调用.Equals时会导致NullReferenceException。因此,如果删除值类型约束,则需要为此方案添加错误处理。

答案 2 :(得分:2)

  

我很想找到更多的方式   优雅,因为我不得不削减和   过去大致相同的代码20次以上   并且只是更改属性名称。

代码生成器就是为了这个目的而存在的。但是如果你不想走这条路,你可以将代码缩短到这个:

return allFoos.All(foo => foo.FooVar1 == defaultFoo.FooVar1);
相关问题