@@ -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