Browse Source

Merge pull request #1034 from AvaloniaUI/fixes/1033-dont-use-weakreference-in-bindingnotification

Don't use WeakReference in BindingNotification.
pull/1042/head
Steven Kirk 9 years ago
committed by GitHub
parent
commit
fc1308ef98
  1. 36
      src/Avalonia.Base/Data/BindingNotification.cs

36
src/Avalonia.Base/Data/BindingNotification.cs

@ -44,11 +44,7 @@ namespace Avalonia.Data
public static readonly BindingNotification UnsetValue = public static readonly BindingNotification UnsetValue =
new BindingNotification(AvaloniaProperty.UnsetValue); new BindingNotification(AvaloniaProperty.UnsetValue);
// Null cannot be held in WeakReference as it's indistinguishable from an expired value so private object _value;
// use this value in its place.
private static readonly object NullValue = new object();
private WeakReference<object> _value;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="BindingNotification"/> class. /// Initializes a new instance of the <see cref="BindingNotification"/> class.
@ -56,7 +52,7 @@ namespace Avalonia.Data
/// <param name="value">The binding value.</param> /// <param name="value">The binding value.</param>
public BindingNotification(object value) public BindingNotification(object value)
{ {
_value = new WeakReference<object>(value ?? NullValue); _value = value;
} }
/// <summary> /// <summary>
@ -73,6 +69,7 @@ namespace Avalonia.Data
Error = error; Error = error;
ErrorType = errorType; ErrorType = errorType;
_value = AvaloniaProperty.UnsetValue;
} }
/// <summary> /// <summary>
@ -84,7 +81,7 @@ namespace Avalonia.Data
public BindingNotification(Exception error, BindingErrorType errorType, object fallbackValue) public BindingNotification(Exception error, BindingErrorType errorType, object fallbackValue)
: this(error, errorType) : this(error, errorType)
{ {
_value = new WeakReference<object>(fallbackValue ?? NullValue); _value = fallbackValue;
} }
/// <summary> /// <summary>
@ -95,31 +92,12 @@ namespace Avalonia.Data
/// If this property is read when <see cref="HasValue"/> is false then it will return /// If this property is read when <see cref="HasValue"/> is false then it will return
/// <see cref="AvaloniaProperty.UnsetValue"/>. /// <see cref="AvaloniaProperty.UnsetValue"/>.
/// </remarks> /// </remarks>
public object Value public object Value => _value;
{
get
{
if (_value != null)
{
object result;
if (_value.TryGetTarget(out result))
{
return result == NullValue ? null : result;
}
}
// There's the possibility of a race condition in that HasValue can return true,
// and then the value is GC'd before Value is read. We should be ok though as
// we return UnsetValue which should be a safe alternative.
return AvaloniaProperty.UnsetValue;
}
}
/// <summary> /// <summary>
/// Gets a value indicating whether <see cref="Value"/> should be pushed to the target. /// Gets a value indicating whether <see cref="Value"/> should be pushed to the target.
/// </summary> /// </summary>
public bool HasValue => _value != null; public bool HasValue => _value != AvaloniaProperty.UnsetValue;
/// <summary> /// <summary>
/// Gets the error that occurred on the source, if any. /// Gets the error that occurred on the source, if any.
@ -256,7 +234,7 @@ namespace Avalonia.Data
/// </summary> /// </summary>
public void SetValue(object value) public void SetValue(object value)
{ {
_value = new WeakReference<object>(value ?? NullValue); _value = value;
} }
/// <inheritdoc/> /// <inheritdoc/>

Loading…
Cancel
Save