Make MarkupExtension.ProvideValue method inlinable for StaticResourceExtension and ResolveByNameExtension (#17659)

This commit is contained in:
Max Katz 2024-12-03 16:59:27 +00:00 коммит произвёл GitHub
Родитель 44a6f91bc5
Коммит a530bbeb99
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
2 изменённых файлов: 18 добавлений и 12 удалений

Просмотреть файл

@ -1,4 +1,5 @@
using System;
using System.Runtime.CompilerServices;
using Avalonia.Controls;
using Avalonia.Data.Core;
@ -13,14 +14,17 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
public string Name { get; }
public object? ProvideValue(IServiceProvider serviceProvider)
public object? ProvideValue(IServiceProvider serviceProvider) => ProvideValue(serviceProvider, Name);
[MethodImpl(MethodImplOptions.NoInlining)]
private static object? ProvideValue(IServiceProvider serviceProvider, string name)
{
var nameScope = serviceProvider.GetService<INameScope>();
if (nameScope is null)
return null;
var value = nameScope.FindAsync(Name);
var value = nameScope.FindAsync(name);
if(value.IsCompleted)
return value.GetResult();

Просмотреть файл

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using Avalonia.Controls;
using Avalonia.Markup.Data;
using Avalonia.Markup.Xaml.Converters;
@ -22,9 +23,14 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
public object? ResourceKey { get; set; }
public object? ProvideValue(IServiceProvider serviceProvider)
// Keep instance method ProvideValue as simple as possible, increasing chance to inline it.
// With modern runtimes, inlining this method also helps to eliminate extension allocation completely.
public object? ProvideValue(IServiceProvider serviceProvider) => ProvideValue(serviceProvider, ResourceKey);
[MethodImpl(MethodImplOptions.NoInlining)]
private static object? ProvideValue(IServiceProvider serviceProvider, object? resourceKey)
{
if (ResourceKey is not { } resourceKey)
if (resourceKey is null)
{
throw new ArgumentException("StaticResourceExtension.ResourceKey must be set.");
}
@ -87,20 +93,16 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
{
// This is stored locally to avoid allocating closure in the outer scope.
var localTargetType = targetType;
var localInstance = this;
var localKeyInstance = resourceKey;
DelayedBinding.Add(target, property, x => localInstance.GetValue(x, localTargetType));
DelayedBinding.Add(target, property, x =>
ColorToBrushConverter.Convert(x.FindResource(localKeyInstance), localTargetType));
return AvaloniaProperty.UnsetValue;
}
throw new KeyNotFoundException($"Static resource '{resourceKey}' not found.");
}
private object? GetValue(StyledElement control, Type? targetType)
{
return ColorToBrushConverter.Convert(control.FindResource(ResourceKey!), targetType);
}
internal static ThemeVariant? GetDictionaryVariant(IAvaloniaXamlIlParentStackProvider? stack)
{
switch (stack)