Browse Source

Avoid constant boxing of StyledProperty default value.

pull/2935/head
Dariusz Komosiński 7 years ago
parent
commit
4e312e909a
  1. 28
      src/Avalonia.Base/BoxedValue.cs
  2. 11
      src/Avalonia.Base/StyledPropertyBase.cs
  3. 14
      src/Avalonia.Base/StyledPropertyMetadata`1.cs

28
src/Avalonia.Base/BoxedValue.cs

@ -0,0 +1,28 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
namespace Avalonia
{
/// <summary>
/// Represents boxed value of type <typeparamref name="T"/>.
/// </summary>
/// <typeparam name="T">Type of stored value.</typeparam>
internal readonly struct BoxedValue<T>
{
public BoxedValue(T value)
{
Boxed = value;
Typed = value;
}
/// <summary>
/// Boxed value.
/// </summary>
public object Boxed { get; }
/// <summary>
/// Typed value.
/// </summary>
public T Typed { get; }
}
}

11
src/Avalonia.Base/StyledPropertyBase.cs

@ -68,7 +68,7 @@ namespace Avalonia
{ {
Contract.Requires<ArgumentNullException>(type != null); Contract.Requires<ArgumentNullException>(type != null);
return GetMetadata(type).DefaultValue; return GetMetadata(type).DefaultValue.Typed;
} }
/// <summary> /// <summary>
@ -164,7 +164,14 @@ namespace Avalonia
} }
/// <inheritdoc/> /// <inheritdoc/>
object IStyledPropertyAccessor.GetDefaultValue(Type type) => GetDefaultValue(type); object IStyledPropertyAccessor.GetDefaultValue(Type type) => GetDefaultBoxedValue(type);
private object GetDefaultBoxedValue(Type type)
{
Contract.Requires<ArgumentNullException>(type != null);
return GetMetadata(type).DefaultValue.Boxed;
}
[DebuggerHidden] [DebuggerHidden]
private Func<IAvaloniaObject, TValue, TValue> Cast<THost>(Func<THost, TValue, TValue> validate) private Func<IAvaloniaObject, TValue, TValue> Cast<THost>(Func<THost, TValue, TValue> validate)

14
src/Avalonia.Base/StyledPropertyMetadata`1.cs

@ -19,26 +19,26 @@ namespace Avalonia
/// <param name="validate">A validation function.</param> /// <param name="validate">A validation function.</param>
/// <param name="defaultBindingMode">The default binding mode.</param> /// <param name="defaultBindingMode">The default binding mode.</param>
public StyledPropertyMetadata( public StyledPropertyMetadata(
TValue defaultValue = default(TValue), TValue defaultValue = default,
Func<IAvaloniaObject, TValue, TValue> validate = null, Func<IAvaloniaObject, TValue, TValue> validate = null,
BindingMode defaultBindingMode = BindingMode.Default) BindingMode defaultBindingMode = BindingMode.Default)
: base(defaultBindingMode) : base(defaultBindingMode)
{ {
DefaultValue = defaultValue; DefaultValue = new BoxedValue<TValue>(defaultValue);
Validate = validate; Validate = validate;
} }
/// <summary> /// <summary>
/// Gets the default value for the property. /// Gets the default value for the property.
/// </summary> /// </summary>
public TValue DefaultValue { get; private set; } internal BoxedValue<TValue> DefaultValue { get; private set; }
/// <summary> /// <summary>
/// Gets the validation callback. /// Gets the validation callback.
/// </summary> /// </summary>
public Func<IAvaloniaObject, TValue, TValue> Validate { get; private set; } public Func<IAvaloniaObject, TValue, TValue> Validate { get; private set; }
object IStyledPropertyMetadata.DefaultValue => DefaultValue; object IStyledPropertyMetadata.DefaultValue => DefaultValue.Boxed;
Func<IAvaloniaObject, object, object> IStyledPropertyMetadata.Validate => Cast(Validate); Func<IAvaloniaObject, object, object> IStyledPropertyMetadata.Validate => Cast(Validate);
@ -47,11 +47,9 @@ namespace Avalonia
{ {
base.Merge(baseMetadata, property); base.Merge(baseMetadata, property);
var src = baseMetadata as StyledPropertyMetadata<TValue>; if (baseMetadata is StyledPropertyMetadata<TValue> src)
if (src != null)
{ {
if (DefaultValue == null) if (DefaultValue.Boxed == null)
{ {
DefaultValue = src.DefaultValue; DefaultValue = src.DefaultValue;
} }

Loading…
Cancel
Save