File tree Expand file tree Collapse file tree
PropertyChangedAnalyzers.Test/INPC002MutablePublicPropertyShouldNotify
PropertyChangedAnalyzers/Helpers Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -1018,5 +1018,56 @@ protected virtual void OnPropertyChanged(string propertyName)
10181018
10191019 RoslynAssert . Valid ( Analyzer , Descriptor , code ) ;
10201020 }
1021+
1022+ [ Test ]
1023+ public static void SettingPropertyOfAnUnrelatedInstance ( )
1024+ {
1025+ var code = @"
1026+ namespace ValidCode
1027+ {
1028+ using System.ComponentModel;
1029+ using System.Runtime.CompilerServices;
1030+
1031+ internal class Settings
1032+ {
1033+ public static Settings Default { get; }
1034+
1035+ public string Address { get; set; }
1036+ }
1037+
1038+ public class SomeViewModel : INotifyPropertyChanged
1039+ {
1040+ private string address;
1041+
1042+ public event PropertyChangedEventHandler? PropertyChanged;
1043+
1044+ public string Address
1045+ {
1046+ get => this.address;
1047+ set
1048+ {
1049+ if (!Set(ref this.address, value)) return;
1050+
1051+ Settings.Default.Address = value;
1052+ }
1053+ }
1054+
1055+ protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
1056+ {
1057+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
1058+ }
1059+
1060+ protected bool Set<T>(ref T location, T value, [CallerMemberName] string propertyName = null)
1061+ {
1062+ if (RuntimeHelpers.Equals(location, value)) return false;
1063+ location = value;
1064+ OnPropertyChanged(propertyName);
1065+ return true;
1066+ }
1067+ }
1068+ }" ;
1069+
1070+ RoslynAssert . Valid ( Analyzer , code ) ;
1071+ }
10211072 }
10221073}
Original file line number Diff line number Diff line change @@ -110,20 +110,19 @@ IdentifierNameSyntax identifierName
110110
111111 internal static AssignmentExpressionSyntax ? AssignsValueToBackingField ( AccessorDeclarationSyntax setter )
112112 {
113+ if ( setter . FirstAncestor < PropertyDeclarationSyntax > ( ) is not { } property || ! property . TrySingleReturned ( out var backingExpression ) )
114+ {
115+ return null ;
116+ }
117+
113118 using var walker = AssignmentWalker . Borrow ( setter ) ;
119+
114120 foreach ( var assignment in walker . Assignments )
115121 {
116- if ( assignment is { Right : IdentifierNameSyntax { Identifier : { ValueText : "value" } } } )
122+ if ( assignment is { Right : IdentifierNameSyntax { Identifier : { ValueText : "value" } } } &&
123+ MemberPath . Equals ( backingExpression , assignment . Left ) )
117124 {
118- switch ( assignment . Left )
119- {
120- case IdentifierNameSyntax _:
121- case MemberAccessExpressionSyntax { Expression : ThisExpressionSyntax _ } :
122- case MemberAccessExpressionSyntax { Expression : IdentifierNameSyntax _ } :
123- case MemberAccessExpressionSyntax { Expression : MemberAccessExpressionSyntax { Expression : IdentifierNameSyntax _ } } :
124- case MemberAccessExpressionSyntax { Expression : MemberAccessExpressionSyntax { Expression : ThisExpressionSyntax _ } } :
125- return assignment ;
126- }
125+ return assignment ;
127126 }
128127 }
129128
Original file line number Diff line number Diff line change 1+ namespace ValidCode
2+ {
3+ using System . ComponentModel ;
4+ using System . Runtime . CompilerServices ;
5+
6+ public class NotMutations : INotifyPropertyChanged
7+ {
8+ public event PropertyChangedEventHandler ? PropertyChanged ;
9+
10+ protected virtual void OnPropertyChanged ( [ CallerMemberName ] string ? propertyName = null )
11+ {
12+ this . PropertyChanged ? . Invoke ( this , new PropertyChangedEventArgs ( propertyName ) ) ;
13+ }
14+
15+ protected bool Set < T > ( ref T location , T value , [ CallerMemberName ] string ? propertyName = null )
16+ {
17+ if ( RuntimeHelpers . Equals ( location , value ) ) return false ;
18+ location = value ;
19+ OnPropertyChanged ( propertyName ) ;
20+ return true ;
21+ }
22+
23+ #pragma warning disable INPC001
24+ internal class Settings
25+ #pragma warning restore INPC001
26+ {
27+ public static Settings Default { get ; } = new ( ) ;
28+
29+ public int SamePropertyNameOnUnrelatedInstance { get ; set ; }
30+ }
31+
32+ private int samePropertyNameOnUnrelatedInstance ;
33+ public int SamePropertyNameOnUnrelatedInstance
34+ {
35+ get => this . samePropertyNameOnUnrelatedInstance ;
36+ set
37+ {
38+ if ( ! Set ( ref samePropertyNameOnUnrelatedInstance , value ) ) return ;
39+
40+ Settings . Default . SamePropertyNameOnUnrelatedInstance = value ;
41+ }
42+ }
43+ }
44+ }
You can’t perform that action at this time.
0 commit comments