2017-02-16 14 views
2

Я вижу очень странное поведение при вычислении значений свойств. У меня есть свойство HasChanged, которое истинно, если любое из его зависимых свойств истинно. Но я получил результат - все аргументы ложны, и результат верен. Я использую структуру MVVM Light, и каждое свойство INotifyPropertyChangedLinq Любой возвращает true, несмотря на то, что все значения в коллекции являются ложными

Здесь находятся вспомогательные функции

private static bool PropertyWrapper(bool value, [CallerMemberName] string callerName = "") 
    { 
     Logger.Debug($"[{callerName}: {value}]"); 
     return value; 
    } 

    private static T PropertyWrapper<T>(Expression<Func<T>> property) 
    { 
     var compiled = property.Compile(); 
     var result = (T)compiled.DynamicInvoke(); 
     Logger.Debug($"[{GetName(property)}: {result}]"); 
     return result; 
    } 

    private static string GetName<T>(Expression<Func<T>> expr) 
    { 
     var mexpr = expr.Body as MemberExpression; 
     if (mexpr == null) return "(null)"; 
     if (mexpr.Member == null) return "((null))"; 
     return mexpr.Member.Name; 
    } 

И это код

public virtual bool HasChanged => PropertyWrapper(new[] { 
     PropertyWrapper(() => TitleChanged), 
     PropertyWrapper(() => EnglishTitleChanged), 
     PropertyWrapper(() => OriginalTitleChanged), 
     PropertyWrapper(() => PlotChanged), 
     PropertyWrapper(() => OutlineChanged), 
     PropertyWrapper(() => DirectorChanged), 
     PropertyWrapper(() => YearChanged), 
     PropertyWrapper(() => MovieRolesChanged), 
     PropertyWrapper(() => GenresChanged), 
     PropertyWrapper(() => CountriesChanged) 
    }.Any(), "HasChanged"); 

    public bool YearChanged => this.state == State.Edit && this.source.MovieDescription.Year != this.clone.MovieDescription.Year; 
    public bool TitleChanged => HasTitleChanges(); 
    public bool EnglishTitleChanged => HasEnglishTitleChanges(); 
    public bool OriginalTitleChanged => HasOriginalTitleChanges(); 
    public bool PlotChanged => HasDescriptionChanges(); 
    public bool DirectorChanged => HasDirectorChanges(); 
    public bool OutlineChanged => HasOutlineChanges(); 
    public bool MovieRolesChanged => HasMovieRolesChanges(); 
    public bool CountriesChanged => HasCountriesChanges(); 
    public bool GenresChanged => HasGenresChanges(); 

и то, что написано для входа

[TitleChanged: False]

[EnglishTitleChanged: Ложный]

[OriginalTitleChanged: Ложный]

[PlotChanged: Ложный]

[OutlineChanged: Ложный]

[DirectorChanged: Ложный]

[YearChanged : False]

[MovieRolesChanged: False]

[GenresChanged: Ложные]

[CountriesChanged: Ложные]

[HasChanged: Правда]

Это выглядит невозможным скучно, но я не могу себе представить, как это может быть. Пожалуйста, объясните мне причину такого поведения.

ответ

5

Any без параметров возвращается, если в коллекции есть какие-либо элементы. Для того, чтобы получить то, что вы хотите, вы должны проверить значение ваших элементов в качестве Any предиката:

public virtual bool HasChanged => PropertyWrapper(new[] { 
     //... 
     }.Any(q => q), "HasChanged"); 
+1

В целом правильное, но элементы Booleans, а не делегатов, поэтому он должен быть '.Any (д => д) ' –

+0

@ ИванСтоев, спасибо, отредактирован. Меня смутило так много лямбда! – slawekwin