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,
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.");
if (target is not StyledElement element)
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.");
if (!typeof(TValue).IsAssignableTo(targetProperty.PropertyType))
if (!valueType.IsAssignableTo(targetProperty.PropertyType))
{
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}'.");
}
_sink = sink;
_frame = frame;
_target = new(element);
TargetProperty = targetProperty;
Priority = priority;
return element;
}
public override void Dispose()

Loading…
Cancel
Save