@@ -488,6 +488,20 @@ static Action<object> GetValidationAction(Type type)
488488 // Fallback method to create the delegate with a compiled LINQ expression
489489 static Action < object > GetValidationActionFallback ( Type type )
490490 {
491+ // Get the collection of all properties to validate
492+ PropertyInfo [ ] validatableProperties = (
493+ from property in type . GetProperties ( BindingFlags . Instance | BindingFlags . Public )
494+ where property . GetIndexParameters ( ) . Length == 0 &&
495+ property . GetCustomAttributes < ValidationAttribute > ( true ) . Any ( ) &&
496+ property . GetMethod is not null
497+ select property ) . ToArray ( ) ;
498+
499+ // Short path if there are no properties to validate
500+ if ( validatableProperties . Length == 0 )
501+ {
502+ return static _ => { } ;
503+ }
504+
491505 // MyViewModel inst0 = (MyViewModel)arg0;
492506 ParameterExpression arg0 = Expression . Parameter ( typeof ( object ) ) ;
493507 UnaryExpression inst0 = Expression . Convert ( arg0 , type ) ;
@@ -513,14 +527,10 @@ static Action<object> GetValidationActionFallback(Type type)
513527 // ObservableValidator externally, but that is fine because IL doesn't really have
514528 // a concept of member visibility, that's purely a C# build-time feature.
515529 BlockExpression body = Expression . Block (
516- from property in type . GetProperties ( BindingFlags . Instance | BindingFlags . Public )
517- where property . GetIndexParameters ( ) . Length == 0 &&
518- property . GetCustomAttributes < ValidationAttribute > ( true ) . Any ( )
519- let getter = property . GetMethod
520- where getter is not null
530+ from property in validatableProperties
521531 select Expression . Call ( inst0 , validateMethod , new Expression [ ]
522532 {
523- Expression . Convert ( Expression . Call ( inst0 , getter ) , typeof ( object ) ) ,
533+ Expression . Convert ( Expression . Call ( inst0 , property . GetMethod ) , typeof ( object ) ) ,
524534 Expression . Constant ( property . Name )
525535 } ) ) ;
526536
0 commit comments