Свойство как параметр?C # - PullRequest
0 голосов
/ 15 января 2010

Итак, у меня есть целая куча опций, каждая отдельная страница / вкладка может иметь свои локальные опции. У нас может быть 10-15 страниц с открытыми вкладками. Мне нужно реализовать способ показа глобальных значений по умолчанию, чтобы все вкладки имели одинаковые значения. Я работаю над частью модели / viewmodel приложения WPF.

Я бы хотел найти более элегантный способ, поскольку мне приходится вырезать и пропустить примерно один и тот же код 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 ]

3 голосов
/ 15 января 2010

Ну, для начала вы определяете как вспомогательные поля, которые никогда не будут использоваться, так и автоматические свойства. Этого достаточно для простого bool свойства:

public bool FooVar1 { get; set; }

Нет необходимости в приватном поле. Это значительно уменьшает количество строк в вашем примере.

2 голосов
/ 15 января 2010

Я бы хотел найти способ, который более элегантный, так как мне приходится резать и прошёл примерно один и тот же код 20+ раз и просто измените имена свойств.

Генераторы кода существуют именно для этой цели. Но если вы не хотите идти по этому пути, вы можете сократить свой код до этого:

return allFoos.All(foo => foo.FooVar1 == defaultFoo.FooVar1);
2 голосов
/ 15 января 2010

Я не совсем уверен, в чем вопрос, но если вы ищете какой-либо способ унифицировать код 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) будет иметь значение null, что вызовет исключение NullReferenceException, когда мы вызовем для него .Equals. Поэтому, если вы удалите ограничение типов значений, вам потребуется добавить обработку ошибок для этого сценария.

...