@@ -206,7 +206,7 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration(
206206                                InvocationExpression ( IdentifierName ( "OnPropertyChanged" ) ) 
207207                                . AddArgumentListArguments ( Argument ( MemberAccessExpression ( 
208208                                    SyntaxKind . SimpleMemberAccessExpression , 
209-                                     AliasQualifiedName ( IdentifierName ( Token ( SyntaxKind . GlobalKeyword ) ) ,   IdentifierName ( " Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs") ) , 
209+                                     IdentifierName ( "global:: Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs") , 
210210                                    IdentifierName ( $ "{ dependentPropertyName } { nameof ( PropertyChangedEventArgs ) } ") ) ) ) ) ) ; 
211211                        } 
212212                        else  if  ( attributeArgument . Kind  ==  TypedConstantKind . Array ) 
@@ -227,7 +227,7 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration(
227227                                    InvocationExpression ( IdentifierName ( "OnPropertyChanged" ) ) 
228228                                    . AddArgumentListArguments ( Argument ( MemberAccessExpression ( 
229229                                        SyntaxKind . SimpleMemberAccessExpression , 
230-                                         AliasQualifiedName ( IdentifierName ( Token ( SyntaxKind . GlobalKeyword ) ) ,   IdentifierName ( " Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs") ) , 
230+                                         IdentifierName ( "global:: Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs") , 
231231                                        IdentifierName ( $ "{ currentPropertyName } { nameof ( PropertyChangedEventArgs ) } ") ) ) ) ) ) ; 
232232                            } 
233233                        } 
@@ -257,32 +257,68 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration(
257257
258258                    setterBlock  =  Block ( ) ; 
259259                } 
260- 
261-                 // Generate the inner setter block as follows: 
262-                 // 
263-                 // SetProperty(ref <FIELD_NAME>, value, true); 
264-                 // 
265-                 // Or in case there is at least one dependent property: 
266-                 // 
267-                 // if (SetProperty(ref <FIELD_NAME>, value, true)) 
268-                 // { 
269-                 //     OnPropertyChanged(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.Property1PropertyChangedEventArgs); // Optional 
270-                 //     OnPropertyChanged(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.Property2PropertyChangedEventArgs); 
271-                 //     ... 
272-                 //     OnPropertyChanged(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.PropertyNPropertyChangedEventArgs); 
273-                 // } 
274-                 InvocationExpressionSyntax  setPropertyExpression  = 
275-                     InvocationExpression ( IdentifierName ( "SetProperty" ) ) 
276-                     . AddArgumentListArguments ( 
277-                         Argument ( IdentifierName ( fieldSymbol . Name ) ) . WithRefOrOutKeyword ( Token ( SyntaxKind . RefKeyword ) ) , 
278-                         Argument ( IdentifierName ( "value" ) ) , 
279-                         Argument ( LiteralExpression ( SyntaxKind . TrueLiteralExpression ) ) ) ; 
280- 
281-                 setterBlock  =  dependentPropertyNotificationStatements . Count  switch 
260+                 else 
282261                { 
283-                     0  =>  Block ( ExpressionStatement ( setPropertyExpression ) ) , 
284-                     _ =>  Block ( IfStatement ( setPropertyExpression ,  Block ( dependentPropertyNotificationStatements ) ) ) 
285-                 } ; 
262+                     propertyChangedNames . Add ( propertyName ) ; 
263+                     propertyChangingNames . Add ( propertyName ) ; 
264+ 
265+                     // Generate the inner setter block as follows: 
266+                     // 
267+                     // if (!global::System.Collections.Generic.EqualityComparer<<FIELD_TYPE>>.Default.Equals(<FIELD_NAME>, value)) 
268+                     // { 
269+                     //     OnPropertyChanging(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.PropertyNamePropertyChangingEventArgs); // Optional 
270+                     //     <FIELD_NAME> = value; 
271+                     //     OnPropertyChanged(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.PropertyNamePropertyChangedEventArgs); 
272+                     //     ValidateProperty(value, <PROPERTY_NAME>); 
273+                     //     OnPropertyChanged(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.Property1PropertyChangedEventArgs); // Optional 
274+                     //     OnPropertyChanged(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.Property2PropertyChangedEventArgs); 
275+                     //     ... 
276+                     //     OnPropertyChanged(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.PropertyNPropertyChangedEventArgs); 
277+                     // } 
278+                     // 
279+                     // The reason why the code is explicitly generated instead of just calling ObservableValidator.SetProperty() is so that we can 
280+                     // take advantage of the cached property changed arguments for the current property as well, not just for the dependent ones. 
281+                     setterBlock  =  Block ( 
282+                         IfStatement ( 
283+                             PrefixUnaryExpression ( 
284+                                 SyntaxKind . LogicalNotExpression , 
285+                                 InvocationExpression ( 
286+                                     MemberAccessExpression ( 
287+                                         SyntaxKind . SimpleMemberAccessExpression , 
288+                                         MemberAccessExpression ( 
289+                                             SyntaxKind . SimpleMemberAccessExpression , 
290+                                             GenericName ( Identifier ( "global::System.Collections.Generic.EqualityComparer" ) ) 
291+                                             . AddTypeArgumentListArguments ( IdentifierName ( typeName ) ) , 
292+                                             IdentifierName ( "Default" ) ) , 
293+                                         IdentifierName ( "Equals" ) ) ) 
294+                                 . AddArgumentListArguments ( 
295+                                     Argument ( IdentifierName ( fieldSymbol . Name ) ) , 
296+                                     Argument ( IdentifierName ( "value" ) ) ) ) , 
297+                             Block ( 
298+                                 ExpressionStatement ( 
299+                                     InvocationExpression ( IdentifierName ( "OnPropertyChanging" ) ) 
300+                                     . AddArgumentListArguments ( Argument ( MemberAccessExpression ( 
301+                                         SyntaxKind . SimpleMemberAccessExpression , 
302+                                         IdentifierName ( "global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs" ) , 
303+                                         IdentifierName ( $ "{ propertyName } { nameof ( PropertyChangingEventArgs ) } ") ) ) ) ) , 
304+                                 ExpressionStatement ( 
305+                                     AssignmentExpression ( 
306+                                         SyntaxKind . SimpleAssignmentExpression , 
307+                                         IdentifierName ( fieldSymbol . Name ) , 
308+                                         IdentifierName ( "value" ) ) ) , 
309+                                 ExpressionStatement ( 
310+                                     InvocationExpression ( IdentifierName ( "OnPropertyChanged" ) ) 
311+                                     . AddArgumentListArguments ( Argument ( MemberAccessExpression ( 
312+                                         SyntaxKind . SimpleMemberAccessExpression , 
313+                                         IdentifierName ( "global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs" ) , 
314+                                         IdentifierName ( $ "{ propertyName } { nameof ( PropertyChangedEventArgs ) } ") ) ) ) ) , 
315+                                 ExpressionStatement ( 
316+                                     InvocationExpression ( IdentifierName ( "ValidateProperty" ) ) 
317+                                     . AddArgumentListArguments ( 
318+                                         Argument ( IdentifierName ( "value" ) ) , 
319+                                         Argument ( LiteralExpression ( SyntaxKind . StringLiteralExpression ,  Literal ( propertyName ) ) ) ) ) ) 
320+                             . AddStatements ( dependentPropertyNotificationStatements . ToArray ( ) ) ) ) ; 
321+                 } 
286322            } 
287323            else 
288324            { 
@@ -297,7 +333,7 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration(
297333                        InvocationExpression ( IdentifierName ( "OnPropertyChanging" ) ) 
298334                        . AddArgumentListArguments ( Argument ( MemberAccessExpression ( 
299335                            SyntaxKind . SimpleMemberAccessExpression , 
300-                             AliasQualifiedName ( IdentifierName ( Token ( SyntaxKind . GlobalKeyword ) ) ,   IdentifierName ( " Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs") ) , 
336+                             IdentifierName ( "global:: Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs") , 
301337                            IdentifierName ( $ "{ propertyName } { nameof ( PropertyChangingEventArgs ) } ") ) ) ) ) ) ; 
302338                } 
303339
@@ -317,7 +353,7 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration(
317353                        InvocationExpression ( IdentifierName ( "OnPropertyChanged" ) ) 
318354                        . AddArgumentListArguments ( Argument ( MemberAccessExpression ( 
319355                            SyntaxKind . SimpleMemberAccessExpression , 
320-                             AliasQualifiedName ( IdentifierName ( Token ( SyntaxKind . GlobalKeyword ) ) ,   IdentifierName ( " Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs") ) , 
356+                             IdentifierName ( "global:: Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs") , 
321357                            IdentifierName ( $ "{ propertyName } { nameof ( PropertyChangedEventArgs ) } ") ) ) ) ) ) ; 
322358
323359                // Add the dependent property notifications at the end 
0 commit comments