Browse Source

Share TypedBindingExpression.Attach validation across instantiations.

Factor the validation logic (most notably the exception string
formatting) out of the generic Attach method into a non-generic static
helper. It only uses typeof(TValue), not TValue, so sharing it avoids
duplicating the code per generic instantiation, a meaningful NativeAOT
size saving (~3.3 KB => ~2.5 KB per instantiation).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pull/21552/head
grokys 3 months ago
parent
commit
3198196b4c
  1. 33
      src/Avalonia.Base/Data/Core/TypedBindingExpression.cs

33
src/Avalonia.Base/Data/Core/TypedBindingExpression.cs

@ -62,25 +62,40 @@ internal class TypedBindingExpression<TSource, TValue> : BindingExpressionBase,
AvaloniaProperty targetProperty, AvaloniaProperty targetProperty,
BindingPriority priority) BindingPriority priority)
{ {
if (_sink is not null) // The validation is factored out into a non-generic static method so that its code (most
// notably the exception string formatting) is shared across all generic instantiations
// instead of being duplicated for each one, which is a meaningful NativeAOT size saving.
var element = ValidateAttach(_sink is not null, TargetProperty, typeof(TValue), target, targetProperty);
_sink = sink;
_frame = frame;
_target = new(element);
TargetProperty = targetProperty;
Priority = priority;
}
private static StyledElement ValidateAttach(
bool alreadyAttached,
AvaloniaProperty? currentTargetProperty,
Type valueType,
AvaloniaObject target,
AvaloniaProperty targetProperty)
{
if (alreadyAttached)
throw new InvalidOperationException("TypedBindingExpression was already attached."); throw new InvalidOperationException("TypedBindingExpression was already attached.");
if (target is not StyledElement element) if (target is not StyledElement element)
throw new InvalidOperationException("TypedBindingExpression may only target StyledElements"); throw new InvalidOperationException("TypedBindingExpression may only target StyledElements");
if (TargetProperty is not null && TargetProperty != targetProperty) if (currentTargetProperty is not null && currentTargetProperty != targetProperty)
throw new InvalidOperationException("TypedBindingExpression was already attached to a different property."); throw new InvalidOperationException("TypedBindingExpression was already attached to a different property.");
if (!typeof(TValue).IsAssignableTo(targetProperty.PropertyType)) if (!valueType.IsAssignableTo(targetProperty.PropertyType))
{ {
throw new InvalidOperationException( throw new InvalidOperationException(
$"TypedBindingExpression of type '{typeof(TValue)}' cannot be bound " + $"TypedBindingExpression of type '{valueType}' cannot be bound " +
$"to a property of type '{targetProperty.PropertyType}'."); $"to a property of type '{targetProperty.PropertyType}'.");
} }
_sink = sink; return element;
_frame = frame;
_target = new(element);
TargetProperty = targetProperty;
Priority = priority;
} }
public override void Dispose() public override void Dispose()

Loading…
Cancel
Save