Browse Source

Nullable annotations for AvaloniaObject/AvaloniaProperty etc. (#7078)

* Add nullable annotations...

...to `AvaloniaObject`/`AvaloniaProperty`-related classes and a few other uncontroversial files.

* Check for null before first use.

* Don't need this check as base class does it.
# Conflicts:
#	src/Avalonia.Styling/Styling/Activators/PropertyEqualsActivator.cs
#	src/Avalonia.Styling/Styling/PropertyEqualsSelector.cs
release/0.10.11-rc.2
Steven Kirk 4 years ago
committed by Dan Walmsley
parent
commit
d914a96654
  1. 2
      src/Avalonia.Animation/Animatable.cs
  2. 4
      src/Avalonia.Base/AttachedProperty.cs
  3. 2
      src/Avalonia.Base/AvaloniaInternalException.cs
  4. 8
      src/Avalonia.Base/AvaloniaObject.cs
  5. 76
      src/Avalonia.Base/AvaloniaObjectExtensions.cs
  6. 99
      src/Avalonia.Base/AvaloniaProperty.cs
  7. 2
      src/Avalonia.Base/AvaloniaPropertyMetadata.cs
  8. 48
      src/Avalonia.Base/AvaloniaPropertyRegistry.cs
  9. 10
      src/Avalonia.Base/AvaloniaProperty`1.cs
  10. 2
      src/Avalonia.Base/Data/BindingValue.cs
  11. 6
      src/Avalonia.Base/Data/Core/IPropertyInfo.cs
  12. 29
      src/Avalonia.Base/DirectProperty.cs
  13. 6
      src/Avalonia.Base/DirectPropertyBase.cs
  14. 6
      src/Avalonia.Base/DirectPropertyMetadata`1.cs
  15. 2
      src/Avalonia.Base/EnumExtensions.cs
  16. 4
      src/Avalonia.Base/IDescription.cs
  17. 6
      src/Avalonia.Base/IDirectPropertyAccessor.cs
  18. 6
      src/Avalonia.Base/IDirectPropertyMetadata.cs
  19. 4
      src/Avalonia.Base/IStyledPropertyAccessor.cs
  20. 4
      src/Avalonia.Base/IStyledPropertyMetadata.cs
  21. 4
      src/Avalonia.Base/Reactive/AvaloniaPropertyBindingObservable.cs
  22. 10
      src/Avalonia.Base/Reactive/TypedBindingAdapter.cs
  23. 6
      src/Avalonia.Base/StyledProperty.cs
  24. 40
      src/Avalonia.Base/StyledPropertyBase.cs
  25. 10
      src/Avalonia.Base/StyledPropertyMetadata`1.cs
  26. 1
      src/Avalonia.Input/Avalonia.Input.csproj
  27. 8
      src/Avalonia.Styling/Styling/Activators/PropertyEqualsActivator.cs
  28. 10
      src/Markup/Avalonia.Markup/Data/TemplateBinding.cs

2
src/Avalonia.Animation/Animatable.cs

@ -232,7 +232,7 @@ namespace Avalonia.Animation
}
}
private object GetAnimationBaseValue(AvaloniaProperty property)
private object? GetAnimationBaseValue(AvaloniaProperty property)
{
var value = this.GetBaseValue(property, BindingPriority.LocalValue);

4
src/Avalonia.Base/AttachedProperty.cs

@ -1,5 +1,7 @@
using System;
#nullable enable
namespace Avalonia
{
/// <summary>
@ -21,7 +23,7 @@ namespace Avalonia
Type ownerType,
StyledPropertyMetadata<TValue> metadata,
bool inherits = false,
Func<TValue, bool> validate = null)
Func<TValue, bool>? validate = null)
: base(name, ownerType, metadata, inherits, validate)
{
}

2
src/Avalonia.Base/AvaloniaInternalException.cs

@ -1,5 +1,7 @@
using System;
#nullable enable
namespace Avalonia
{
/// <summary>

8
src/Avalonia.Base/AvaloniaObject.cs

@ -103,7 +103,7 @@ namespace Avalonia
/// Gets or sets the value of a <see cref="AvaloniaProperty"/>.
/// </summary>
/// <param name="property">The property.</param>
public object this[AvaloniaProperty property]
public object? this[AvaloniaProperty property]
{
get { return GetValue(property); }
set { SetValue(property, value); }
@ -211,7 +211,7 @@ namespace Avalonia
/// See https://github.com/AvaloniaUI/Avalonia/pull/2747 for the discussion that prompted
/// this.
/// </remarks>
public sealed override bool Equals(object obj) => base.Equals(obj);
public sealed override bool Equals(object? obj) => base.Equals(obj);
/// <summary>
/// Gets the hash code for the object.
@ -233,7 +233,7 @@ namespace Avalonia
/// </summary>
/// <param name="property">The property.</param>
/// <returns>The value.</returns>
public object GetValue(AvaloniaProperty property)
public object? GetValue(AvaloniaProperty property)
{
property = property ?? throw new ArgumentNullException(nameof(property));
@ -567,7 +567,7 @@ namespace Avalonia
/// <param name="oldParent">The old inheritance parent.</param>
internal void InheritanceParentChanged<T>(
StyledPropertyBase<T> property,
IAvaloniaObject oldParent)
IAvaloniaObject? oldParent)
{
var oldValue = oldParent switch
{

76
src/Avalonia.Base/AvaloniaObjectExtensions.cs

@ -6,6 +6,8 @@ using System.Reactive.Subjects;
using Avalonia.Data;
using Avalonia.Reactive;
#nullable enable
namespace Avalonia
{
/// <summary>
@ -21,7 +23,7 @@ namespace Avalonia
/// <returns>An <see cref="IBinding"/>.</returns>
public static IBinding ToBinding<T>(this IObservable<T> source)
{
return new BindingAdaptor(source.Select(x => (object)x));
return new BindingAdaptor(source.Select(x => (object?)x));
}
/// <summary>
@ -36,12 +38,11 @@ namespace Avalonia
/// <remarks>
/// The subscription to <paramref name="o"/> is created using a weak reference.
/// </remarks>
public static IObservable<object> GetObservable(this IAvaloniaObject o, AvaloniaProperty property)
public static IObservable<object?> GetObservable(this IAvaloniaObject o, AvaloniaProperty property)
{
Contract.Requires<ArgumentNullException>(o != null);
Contract.Requires<ArgumentNullException>(property != null);
return new AvaloniaPropertyObservable<object>(o, property);
return new AvaloniaPropertyObservable<object?>(
o ?? throw new ArgumentNullException(nameof(o)),
property ?? throw new ArgumentNullException(nameof(property)));
}
/// <summary>
@ -59,10 +60,9 @@ namespace Avalonia
/// </remarks>
public static IObservable<T> GetObservable<T>(this IAvaloniaObject o, AvaloniaProperty<T> property)
{
Contract.Requires<ArgumentNullException>(o != null);
Contract.Requires<ArgumentNullException>(property != null);
return new AvaloniaPropertyObservable<T>(o, property);
return new AvaloniaPropertyObservable<T>(
o ?? throw new ArgumentNullException(nameof(o)),
property ?? throw new ArgumentNullException(nameof(property)));
}
/// <summary>
@ -77,14 +77,13 @@ namespace Avalonia
/// <remarks>
/// The subscription to <paramref name="o"/> is created using a weak reference.
/// </remarks>
public static IObservable<BindingValue<object>> GetBindingObservable(
public static IObservable<BindingValue<object?>> GetBindingObservable(
this IAvaloniaObject o,
AvaloniaProperty property)
{
Contract.Requires<ArgumentNullException>(o != null);
Contract.Requires<ArgumentNullException>(property != null);
return new AvaloniaPropertyBindingObservable<object>(o, property);
return new AvaloniaPropertyBindingObservable<object?>(
o ?? throw new ArgumentNullException(nameof(o)),
property ?? throw new ArgumentNullException(nameof(property)));
}
/// <summary>
@ -104,10 +103,10 @@ namespace Avalonia
this IAvaloniaObject o,
AvaloniaProperty<T> property)
{
Contract.Requires<ArgumentNullException>(o != null);
Contract.Requires<ArgumentNullException>(property != null);
return new AvaloniaPropertyBindingObservable<T>(
o ?? throw new ArgumentNullException(nameof(o)),
property ?? throw new ArgumentNullException(nameof(property)));
return new AvaloniaPropertyBindingObservable<T>(o, property);
}
/// <summary>
@ -125,10 +124,9 @@ namespace Avalonia
this IAvaloniaObject o,
AvaloniaProperty property)
{
Contract.Requires<ArgumentNullException>(o != null);
Contract.Requires<ArgumentNullException>(property != null);
return new AvaloniaPropertyChangedObservable(o, property);
return new AvaloniaPropertyChangedObservable(
o ?? throw new ArgumentNullException(nameof(o)),
property ?? throw new ArgumentNullException(nameof(property)));
}
/// <summary>
@ -143,13 +141,13 @@ namespace Avalonia
/// An <see cref="ISubject{Object}"/> which can be used for two-way binding to/from the
/// property.
/// </returns>
public static ISubject<object> GetSubject(
public static ISubject<object?> GetSubject(
this IAvaloniaObject o,
AvaloniaProperty property,
BindingPriority priority = BindingPriority.LocalValue)
{
return Subject.Create<object>(
Observer.Create<object>(x => o.SetValue(property, x, priority)),
return Subject.Create<object?>(
Observer.Create<object?>(x => o.SetValue(property, x, priority)),
o.GetObservable(property));
}
@ -188,13 +186,13 @@ namespace Avalonia
/// An <see cref="ISubject{Object}"/> which can be used for two-way binding to/from the
/// property.
/// </returns>
public static ISubject<BindingValue<object>> GetBindingSubject(
public static ISubject<BindingValue<object?>> GetBindingSubject(
this IAvaloniaObject o,
AvaloniaProperty property,
BindingPriority priority = BindingPriority.LocalValue)
{
return Subject.Create<BindingValue<object>>(
Observer.Create<BindingValue<object>>(x =>
return Subject.Create<BindingValue<object?>>(
Observer.Create<BindingValue<object?>>(x =>
{
if (x.HasValue)
{
@ -246,7 +244,7 @@ namespace Avalonia
public static IDisposable Bind(
this IAvaloniaObject target,
AvaloniaProperty property,
IObservable<BindingValue<object>> source,
IObservable<BindingValue<object?>> source,
BindingPriority priority = BindingPriority.LocalValue)
{
target = target ?? throw new ArgumentNullException(nameof(target));
@ -298,7 +296,7 @@ namespace Avalonia
public static IDisposable Bind(
this IAvaloniaObject target,
AvaloniaProperty property,
IObservable<object> source,
IObservable<object?> source,
BindingPriority priority = BindingPriority.LocalValue)
{
target = target ?? throw new ArgumentNullException(nameof(target));
@ -354,7 +352,7 @@ namespace Avalonia
this IAvaloniaObject target,
AvaloniaProperty property,
IBinding binding,
object anchor = null)
object? anchor = null)
{
target = target ?? throw new ArgumentNullException(nameof(target));
property = property ?? throw new ArgumentNullException(nameof(property));
@ -420,7 +418,7 @@ namespace Avalonia
/// <param name="target">The object.</param>
/// <param name="property">The property.</param>
/// <returns>The value.</returns>
public static object GetValue(this IAvaloniaObject target, AvaloniaProperty property)
public static object? GetValue(this IAvaloniaObject target, AvaloniaProperty property)
{
target = target ?? throw new ArgumentNullException(nameof(target));
property = property ?? throw new ArgumentNullException(nameof(property));
@ -462,7 +460,7 @@ namespace Avalonia
///
/// For direct properties returns <see cref="GetValue(IAvaloniaObject, AvaloniaProperty)"/>.
/// </remarks>
public static object GetBaseValue(
public static object? GetBaseValue(
this IAvaloniaObject target,
AvaloniaProperty property,
BindingPriority maxPriority)
@ -517,10 +515,10 @@ namespace Avalonia
/// <returns>
/// An <see cref="IDisposable"/> if setting the property can be undone, otherwise null.
/// </returns>
public static IDisposable SetValue(
public static IDisposable? SetValue(
this IAvaloniaObject target,
AvaloniaProperty property,
object value,
object? value,
BindingPriority priority = BindingPriority.LocalValue)
{
target = target ?? throw new ArgumentNullException(nameof(target));
@ -540,7 +538,7 @@ namespace Avalonia
/// <returns>
/// An <see cref="IDisposable"/> if setting the property can be undone, otherwise null.
/// </returns>
public static IDisposable SetValue<T>(
public static IDisposable? SetValue<T>(
this IAvaloniaObject target,
AvaloniaProperty<T> property,
T value,
@ -633,9 +631,9 @@ namespace Avalonia
private class BindingAdaptor : IBinding
{
private IObservable<object> _source;
private IObservable<object?> _source;
public BindingAdaptor(IObservable<object> source)
public BindingAdaptor(IObservable<object?> source)
{
this._source = source;
}
@ -643,7 +641,7 @@ namespace Avalonia
public InstancedBinding Initiate(
IAvaloniaObject target,
AvaloniaProperty targetProperty,
object anchor = null,
object? anchor = null,
bool enableDataValidation = false)
{
return InstancedBinding.OneWay(_source);

99
src/Avalonia.Base/AvaloniaProperty.cs

@ -4,6 +4,8 @@ using Avalonia.Data;
using Avalonia.Data.Core;
using Avalonia.Utilities;
#nullable enable
namespace Avalonia
{
/// <summary>
@ -36,12 +38,9 @@ namespace Avalonia
Type valueType,
Type ownerType,
AvaloniaPropertyMetadata metadata,
Action<IAvaloniaObject, bool> notifying = null)
Action<IAvaloniaObject, bool>? notifying = null)
{
Contract.Requires<ArgumentNullException>(name != null);
Contract.Requires<ArgumentNullException>(valueType != null);
Contract.Requires<ArgumentNullException>(ownerType != null);
Contract.Requires<ArgumentNullException>(metadata != null);
_ = name ?? throw new ArgumentNullException(nameof(name));
if (name.Contains("."))
{
@ -51,12 +50,12 @@ namespace Avalonia
_metadata = new Dictionary<Type, AvaloniaPropertyMetadata>();
Name = name;
PropertyType = valueType;
OwnerType = ownerType;
PropertyType = valueType ?? throw new ArgumentNullException(nameof(valueType));
OwnerType = ownerType ?? throw new ArgumentNullException(nameof(ownerType));
Notifying = notifying;
Id = s_nextId++;
_metadata.Add(ownerType, metadata);
_metadata.Add(ownerType, metadata ?? throw new ArgumentNullException(nameof(metadata)));
_defaultMetadata = metadata;
}
@ -69,16 +68,13 @@ namespace Avalonia
protected AvaloniaProperty(
AvaloniaProperty source,
Type ownerType,
AvaloniaPropertyMetadata metadata)
AvaloniaPropertyMetadata? metadata)
{
Contract.Requires<ArgumentNullException>(source != null);
Contract.Requires<ArgumentNullException>(ownerType != null);
_metadata = new Dictionary<Type, AvaloniaPropertyMetadata>();
Name = source.Name;
Name = source?.Name ?? throw new ArgumentNullException(nameof(source));
PropertyType = source.PropertyType;
OwnerType = ownerType;
OwnerType = ownerType ?? throw new ArgumentNullException(nameof(ownerType));
Notifying = source.Notifying;
Id = source.Id;
_defaultMetadata = source._defaultMetadata;
@ -149,7 +145,7 @@ namespace Avalonia
/// will be true before the property change notifications are sent and false afterwards. This
/// callback is intended to support Control.IsDataContextChanging.
/// </remarks>
public Action<IAvaloniaObject, bool> Notifying { get; }
public Action<IAvaloniaObject, bool>? Notifying { get; }
/// <summary>
/// Gets the integer ID that represents this property.
@ -192,13 +188,13 @@ namespace Avalonia
/// <param name="a">The first property.</param>
/// <param name="b">The second property.</param>
/// <returns>True if the properties are equal, otherwise false.</returns>
public static bool operator ==(AvaloniaProperty a, AvaloniaProperty b)
public static bool operator ==(AvaloniaProperty? a, AvaloniaProperty? b)
{
if (object.ReferenceEquals(a, b))
{
return true;
}
else if (((object)a == null) || ((object)b == null))
else if (a is null || b is null)
{
return false;
}
@ -214,7 +210,7 @@ namespace Avalonia
/// <param name="a">The first property.</param>
/// <param name="b">The second property.</param>
/// <returns>True if the properties are equal, otherwise false.</returns>
public static bool operator !=(AvaloniaProperty a, AvaloniaProperty b)
public static bool operator !=(AvaloniaProperty? a, AvaloniaProperty? b)
{
return !(a == b);
}
@ -238,15 +234,15 @@ namespace Avalonia
/// <returns>A <see cref="StyledProperty{TValue}"/></returns>
public static StyledProperty<TValue> Register<TOwner, TValue>(
string name,
TValue defaultValue = default(TValue),
TValue defaultValue = default!,
bool inherits = false,
BindingMode defaultBindingMode = BindingMode.OneWay,
Func<TValue, bool> validate = null,
Func<IAvaloniaObject, TValue, TValue> coerce = null,
Action<IAvaloniaObject, bool> notifying = null)
Func<TValue, bool>? validate = null,
Func<IAvaloniaObject, TValue, TValue>? coerce = null,
Action<IAvaloniaObject, bool>? notifying = null)
where TOwner : IAvaloniaObject
{
Contract.Requires<ArgumentNullException>(name != null);
_ = name ?? throw new ArgumentNullException(nameof(name));
var metadata = new StyledPropertyMetadata<TValue>(
defaultValue,
@ -279,14 +275,14 @@ namespace Avalonia
/// <returns>A <see cref="AvaloniaProperty{TValue}"/></returns>
public static AttachedProperty<TValue> RegisterAttached<TOwner, THost, TValue>(
string name,
TValue defaultValue = default(TValue),
TValue defaultValue = default!,
bool inherits = false,
BindingMode defaultBindingMode = BindingMode.OneWay,
Func<TValue, bool> validate = null,
Func<IAvaloniaObject, TValue, TValue> coerce = null)
Func<TValue, bool>? validate = null,
Func<IAvaloniaObject, TValue, TValue>? coerce = null)
where THost : IAvaloniaObject
{
Contract.Requires<ArgumentNullException>(name != null);
_ = name ?? throw new ArgumentNullException(nameof(name));
var metadata = new StyledPropertyMetadata<TValue>(
defaultValue,
@ -316,14 +312,14 @@ namespace Avalonia
public static AttachedProperty<TValue> RegisterAttached<THost, TValue>(
string name,
Type ownerType,
TValue defaultValue = default(TValue),
TValue defaultValue = default!,
bool inherits = false,
BindingMode defaultBindingMode = BindingMode.OneWay,
Func<TValue, bool> validate = null,
Func<IAvaloniaObject, TValue, TValue> coerce = null)
Func<TValue, bool>? validate = null,
Func<IAvaloniaObject, TValue, TValue>? coerce = null)
where THost : IAvaloniaObject
{
Contract.Requires<ArgumentNullException>(name != null);
_ = name ?? throw new ArgumentNullException(nameof(name));
var metadata = new StyledPropertyMetadata<TValue>(
defaultValue,
@ -354,14 +350,14 @@ namespace Avalonia
public static DirectProperty<TOwner, TValue> RegisterDirect<TOwner, TValue>(
string name,
Func<TOwner, TValue> getter,
Action<TOwner, TValue> setter = null,
TValue unsetValue = default(TValue),
Action<TOwner, TValue>? setter = null,
TValue unsetValue = default!,
BindingMode defaultBindingMode = BindingMode.OneWay,
bool enableDataValidation = false)
where TOwner : IAvaloniaObject
{
Contract.Requires<ArgumentNullException>(name != null);
Contract.Requires<ArgumentNullException>(getter != null);
_ = name ?? throw new ArgumentNullException(nameof(name));
_ = getter ?? throw new ArgumentNullException(nameof(getter));
var metadata = new DirectPropertyMetadata<TValue>(
unsetValue: unsetValue,
@ -394,16 +390,16 @@ namespace Avalonia
}
/// <inheritdoc/>
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
var p = obj as AvaloniaProperty;
return p != null && Equals(p);
return p is not null && Equals(p);
}
/// <inheritdoc/>
public bool Equals(AvaloniaProperty other)
public bool Equals(AvaloniaProperty? other)
{
return other != null && Id == other.Id;
return Id == other?.Id;
}
/// <inheritdoc/>
@ -431,7 +427,6 @@ namespace Avalonia
/// <returns>
/// The property metadata.
/// </returns>
///
public AvaloniaPropertyMetadata GetMetadata(Type type)
{
if (!_hasMetadataOverrides)
@ -447,9 +442,9 @@ namespace Avalonia
/// </summary>
/// <param name="value">The value.</param>
/// <returns>True if the value is valid, otherwise false.</returns>
public bool IsValidValue(object value)
public bool IsValidValue(object? value)
{
return TypeUtilities.TryConvertImplicit(PropertyType, value, out value);
return TypeUtilities.TryConvertImplicit(PropertyType, value, out _);
}
/// <summary>
@ -480,14 +475,14 @@ namespace Avalonia
/// Routes an untyped GetValue call to a typed call.
/// </summary>
/// <param name="o">The object instance.</param>
internal abstract object RouteGetValue(IAvaloniaObject o);
internal abstract object? RouteGetValue(IAvaloniaObject o);
/// <summary>
/// Routes an untyped GetBaseValue call to a typed call.
/// </summary>
/// <param name="o">The object instance.</param>
/// <param name="maxPriority">The maximum priority for the value.</param>
internal abstract object RouteGetBaseValue(IAvaloniaObject o, BindingPriority maxPriority);
internal abstract object? RouteGetBaseValue(IAvaloniaObject o, BindingPriority maxPriority);
/// <summary>
/// Routes an untyped SetValue call to a typed call.
@ -498,9 +493,9 @@ namespace Avalonia
/// <returns>
/// An <see cref="IDisposable"/> if setting the property can be undone, otherwise null.
/// </returns>
internal abstract IDisposable RouteSetValue(
internal abstract IDisposable? RouteSetValue(
IAvaloniaObject o,
object value,
object? value,
BindingPriority priority);
/// <summary>
@ -511,10 +506,10 @@ namespace Avalonia
/// <param name="priority">The priority.</param>
internal abstract IDisposable RouteBind(
IAvaloniaObject o,
IObservable<BindingValue<object>> source,
IObservable<BindingValue<object?>> source,
BindingPriority priority);
internal abstract void RouteInheritanceParentChanged(AvaloniaObject o, IAvaloniaObject oldParent);
internal abstract void RouteInheritanceParentChanged(AvaloniaObject o, IAvaloniaObject? oldParent);
/// <summary>
/// Overrides the metadata for the property on the specified type.
@ -523,8 +518,8 @@ namespace Avalonia
/// <param name="metadata">The metadata.</param>
protected void OverrideMetadata(Type type, AvaloniaPropertyMetadata metadata)
{
Contract.Requires<ArgumentNullException>(type != null);
Contract.Requires<ArgumentNullException>(metadata != null);
_ = type ?? throw new ArgumentNullException(nameof(type));
_ = metadata ?? throw new ArgumentNullException(nameof(metadata));
if (_metadata.ContainsKey(type))
{
@ -575,8 +570,8 @@ namespace Avalonia
bool IPropertyInfo.CanGet => true;
bool IPropertyInfo.CanSet => true;
object IPropertyInfo.Get(object target) => ((AvaloniaObject)target).GetValue(this);
void IPropertyInfo.Set(object target, object value) => ((AvaloniaObject)target).SetValue(this, value);
object? IPropertyInfo.Get(object target) => ((AvaloniaObject)target).GetValue(this);
void IPropertyInfo.Set(object target, object? value) => ((AvaloniaObject)target).SetValue(this, value);
}
/// <summary>

2
src/Avalonia.Base/AvaloniaPropertyMetadata.cs

@ -1,5 +1,7 @@
using Avalonia.Data;
#nullable enable
namespace Avalonia
{
/// <summary>

48
src/Avalonia.Base/AvaloniaPropertyRegistry.cs

@ -2,6 +2,8 @@ using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
#nullable enable
namespace Avalonia
{
/// <summary>
@ -44,7 +46,7 @@ namespace Avalonia
/// <returns>A collection of <see cref="AvaloniaProperty"/> definitions.</returns>
public IReadOnlyList<AvaloniaProperty> GetRegistered(Type type)
{
Contract.Requires<ArgumentNullException>(type != null);
_ = type ?? throw new ArgumentNullException(nameof(type));
if (_registeredCache.TryGetValue(type, out var result))
{
@ -78,7 +80,7 @@ namespace Avalonia
/// <returns>A collection of <see cref="AvaloniaProperty"/> definitions.</returns>
public IReadOnlyList<AvaloniaProperty> GetRegisteredAttached(Type type)
{
Contract.Requires<ArgumentNullException>(type != null);
_ = type ?? throw new ArgumentNullException(nameof(type));
if (_attachedCache.TryGetValue(type, out var result))
{
@ -109,7 +111,7 @@ namespace Avalonia
/// <returns>A collection of <see cref="AvaloniaProperty"/> definitions.</returns>
public IReadOnlyList<AvaloniaProperty> GetRegisteredDirect(Type type)
{
Contract.Requires<ArgumentNullException>(type != null);
_ = type ?? throw new ArgumentNullException(nameof(type));
if (_directCache.TryGetValue(type, out var result))
{
@ -140,7 +142,7 @@ namespace Avalonia
/// <returns>A collection of <see cref="AvaloniaProperty"/> definitions.</returns>
public IReadOnlyList<AvaloniaProperty> GetRegisteredInherited(Type type)
{
Contract.Requires<ArgumentNullException>(type != null);
_ = type ?? throw new ArgumentNullException(nameof(type));
if (_inheritedCache.TryGetValue(type, out var result))
{
@ -191,18 +193,18 @@ namespace Avalonia
/// <returns>A collection of <see cref="AvaloniaProperty"/> definitions.</returns>
public IReadOnlyList<AvaloniaProperty> GetRegistered(IAvaloniaObject o)
{
Contract.Requires<ArgumentNullException>(o != null);
_ = o ?? throw new ArgumentNullException(nameof(o));
return GetRegistered(o.GetType());
}
/// <summary>
/// Finds a direct property as registered on an object.
/// Gets a direct property as registered on an object.
/// </summary>
/// <param name="o">The object.</param>
/// <param name="property">The direct property.</param>
/// <returns>
/// The registered property or null if no matching property found.
/// The registered.
/// </returns>
public DirectPropertyBase<T> GetRegisteredDirect<T>(
IAvaloniaObject o,
@ -223,10 +225,10 @@ namespace Avalonia
/// <exception cref="InvalidOperationException">
/// The property name contains a '.'.
/// </exception>
public AvaloniaProperty FindRegistered(Type type, string name)
public AvaloniaProperty? FindRegistered(Type type, string name)
{
Contract.Requires<ArgumentNullException>(type != null);
Contract.Requires<ArgumentNullException>(name != null);
_ = type ?? throw new ArgumentNullException(nameof(type));
_ = name ?? throw new ArgumentNullException(nameof(name));
if (name.Contains("."))
{
@ -260,10 +262,10 @@ namespace Avalonia
/// <exception cref="InvalidOperationException">
/// The property name contains a '.'.
/// </exception>
public AvaloniaProperty FindRegistered(IAvaloniaObject o, string name)
public AvaloniaProperty? FindRegistered(IAvaloniaObject o, string name)
{
Contract.Requires<ArgumentNullException>(o != null);
Contract.Requires<ArgumentNullException>(name != null);
_ = o ?? throw new ArgumentNullException(nameof(o));
_ = name ?? throw new ArgumentNullException(nameof(name));
return FindRegistered(o.GetType(), name);
}
@ -276,7 +278,7 @@ namespace Avalonia
/// <returns>
/// The registered property or null if no matching property found.
/// </returns>
public DirectPropertyBase<T> FindRegisteredDirect<T>(
public DirectPropertyBase<T>? FindRegisteredDirect<T>(
IAvaloniaObject o,
DirectPropertyBase<T> property)
{
@ -306,7 +308,7 @@ namespace Avalonia
/// </summary>
/// <param name="id">The property Id.</param>
/// <returns>The registered property or null if no matching property found.</returns>
internal AvaloniaProperty FindRegistered(int id)
internal AvaloniaProperty? FindRegistered(int id)
{
return id < _properties.Count ? _properties[id] : null;
}
@ -319,8 +321,8 @@ namespace Avalonia
/// <returns>True if the property is registered, otherwise false.</returns>
public bool IsRegistered(Type type, AvaloniaProperty property)
{
Contract.Requires<ArgumentNullException>(type != null);
Contract.Requires<ArgumentNullException>(property != null);
_ = type ?? throw new ArgumentNullException(nameof(type));
_ = property ?? throw new ArgumentNullException(nameof(property));
static bool ContainsProperty(IReadOnlyList<AvaloniaProperty> properties, AvaloniaProperty property)
{
@ -349,8 +351,8 @@ namespace Avalonia
/// <returns>True if the property is registered, otherwise false.</returns>
public bool IsRegistered(object o, AvaloniaProperty property)
{
Contract.Requires<ArgumentNullException>(o != null);
Contract.Requires<ArgumentNullException>(property != null);
_ = o ?? throw new ArgumentNullException(nameof(o));
_ = property ?? throw new ArgumentNullException(nameof(property));
return IsRegistered(o.GetType(), property);
}
@ -367,8 +369,8 @@ namespace Avalonia
/// </remarks>
public void Register(Type type, AvaloniaProperty property)
{
Contract.Requires<ArgumentNullException>(type != null);
Contract.Requires<ArgumentNullException>(property != null);
_ = type ?? throw new ArgumentNullException(nameof(type));
_ = property ?? throw new ArgumentNullException(nameof(property));
if (!_registered.TryGetValue(type, out var inner))
{
@ -418,8 +420,8 @@ namespace Avalonia
/// </remarks>
public void RegisterAttached(Type type, AvaloniaProperty property)
{
Contract.Requires<ArgumentNullException>(type != null);
Contract.Requires<ArgumentNullException>(property != null);
_ = type ?? throw new ArgumentNullException(nameof(type));
_ = property ?? throw new ArgumentNullException(nameof(property));
if (!property.IsAttached)
{

10
src/Avalonia.Base/AvaloniaProperty`1.cs

@ -3,6 +3,8 @@ using System.Reactive.Subjects;
using Avalonia.Data;
using Avalonia.Utilities;
#nullable enable
namespace Avalonia
{
/// <summary>
@ -24,7 +26,7 @@ namespace Avalonia
string name,
Type ownerType,
AvaloniaPropertyMetadata metadata,
Action<IAvaloniaObject, bool> notifying = null)
Action<IAvaloniaObject, bool>? notifying = null)
: base(name, typeof(TValue), ownerType, metadata, notifying)
{
_changed = new Subject<AvaloniaPropertyChangedEventArgs<TValue>>();
@ -40,7 +42,7 @@ namespace Avalonia
protected AvaloniaProperty(
AvaloniaProperty source,
Type ownerType,
AvaloniaPropertyMetadata metadata)
AvaloniaPropertyMetadata? metadata)
: this(source as AvaloniaProperty<TValue> ?? throw new InvalidOperationException(), ownerType, metadata)
{
}
@ -54,7 +56,7 @@ namespace Avalonia
protected AvaloniaProperty(
AvaloniaProperty<TValue> source,
Type ownerType,
AvaloniaPropertyMetadata metadata)
AvaloniaPropertyMetadata? metadata)
: base(source, ownerType, metadata)
{
_changed = source._changed;
@ -82,7 +84,7 @@ namespace Avalonia
protected override IObservable<AvaloniaPropertyChangedEventArgs> GetChanged() => Changed;
protected BindingValue<object> TryConvert(object value)
protected BindingValue<object> TryConvert(object? value)
{
if (value == UnsetValue)
{

2
src/Avalonia.Base/Data/BindingValue.cs

@ -416,7 +416,7 @@ namespace Avalonia.Data
/// <remarks>
/// Note that this method uses reflection and as such may be slow.
/// </remarks>
public static BindingValue<T> Convert<T>(this BindingValue<object> value)
public static BindingValue<T> Convert<T>(this BindingValue<object?> value)
{
return value.Type switch
{

6
src/Avalonia.Base/Data/Core/IPropertyInfo.cs

@ -1,12 +1,14 @@
using System;
#nullable enable
namespace Avalonia.Data.Core
{
public interface IPropertyInfo
{
string Name { get; }
object Get(object target);
void Set(object target, object value);
object? Get(object target);
void Set(object target, object? value);
bool CanSet { get; }
bool CanGet { get; }
Type PropertyType { get; }

29
src/Avalonia.Base/DirectProperty.cs

@ -1,6 +1,9 @@
using System;
using System.Diagnostics.CodeAnalysis;
using Avalonia.Data;
#nullable enable
namespace Avalonia
{
/// <summary>
@ -26,13 +29,11 @@ namespace Avalonia
public DirectProperty(
string name,
Func<TOwner, TValue> getter,
Action<TOwner, TValue> setter,
Action<TOwner, TValue>? setter,
DirectPropertyMetadata<TValue> metadata)
: base(name, typeof(TOwner), metadata)
{
Contract.Requires<ArgumentNullException>(getter != null);
Getter = getter;
Getter = getter ?? throw new ArgumentNullException(nameof(getter));
Setter = setter;
}
@ -46,13 +47,11 @@ namespace Avalonia
private DirectProperty(
DirectPropertyBase<TValue> source,
Func<TOwner, TValue> getter,
Action<TOwner, TValue> setter,
Action<TOwner, TValue>? setter,
DirectPropertyMetadata<TValue> metadata)
: base(source, typeof(TOwner), metadata)
{
Contract.Requires<ArgumentNullException>(getter != null);
Getter = getter;
Getter = getter ?? throw new ArgumentNullException(nameof(getter));
Setter = setter;
}
@ -73,7 +72,7 @@ namespace Avalonia
/// <summary>
/// Gets the setter function.
/// </summary>
public Action<TOwner, TValue> Setter { get; }
public Action<TOwner, TValue>? Setter { get; }
/// <summary>
/// Registers the direct property on another type.
@ -91,8 +90,8 @@ namespace Avalonia
/// <returns>The property.</returns>
public DirectProperty<TNewOwner, TValue> AddOwner<TNewOwner>(
Func<TNewOwner, TValue> getter,
Action<TNewOwner, TValue> setter = null,
TValue unsetValue = default(TValue),
Action<TNewOwner, TValue>? setter = null,
TValue unsetValue = default!,
BindingMode defaultBindingMode = BindingMode.Default,
bool enableDataValidation = false)
where TNewOwner : AvaloniaObject
@ -131,7 +130,7 @@ namespace Avalonia
public DirectProperty<TNewOwner, TValue> AddOwnerWithDataValidation<TNewOwner>(
Func<TNewOwner, TValue> getter,
Action<TNewOwner,TValue> setter,
TValue unsetValue = default(TValue),
TValue unsetValue = default!,
BindingMode defaultBindingMode = BindingMode.Default,
bool enableDataValidation = false)
where TNewOwner : AvaloniaObject
@ -174,20 +173,20 @@ namespace Avalonia
}
/// <inheritdoc/>
object IDirectPropertyAccessor.GetValue(IAvaloniaObject instance)
object? IDirectPropertyAccessor.GetValue(IAvaloniaObject instance)
{
return Getter((TOwner)instance);
}
/// <inheritdoc/>
void IDirectPropertyAccessor.SetValue(IAvaloniaObject instance, object value)
void IDirectPropertyAccessor.SetValue(IAvaloniaObject instance, object? value)
{
if (Setter == null)
{
throw new ArgumentException($"The property {Name} is readonly.");
}
Setter((TOwner)instance, (TValue)value);
Setter((TOwner)instance, (TValue)value!);
}
}
}

6
src/Avalonia.Base/DirectPropertyBase.cs

@ -148,7 +148,7 @@ namespace Avalonia
/// <inheritdoc/>
internal override IDisposable? RouteSetValue(
IAvaloniaObject o,
object value,
object? value,
BindingPriority priority)
{
var v = TryConvert(value);
@ -172,14 +172,14 @@ namespace Avalonia
/// <inheritdoc/>
internal override IDisposable RouteBind(
IAvaloniaObject o,
IObservable<BindingValue<object>> source,
IObservable<BindingValue<object?>> source,
BindingPriority priority)
{
var adapter = TypedBindingAdapter<TValue>.Create(o, this, source);
return o.Bind<TValue>(this, adapter);
}
internal override void RouteInheritanceParentChanged(AvaloniaObject o, IAvaloniaObject oldParent)
internal override void RouteInheritanceParentChanged(AvaloniaObject o, IAvaloniaObject? oldParent)
{
throw new NotSupportedException("Direct properties do not support inheritance.");
}

6
src/Avalonia.Base/DirectPropertyMetadata`1.cs

@ -1,5 +1,7 @@
using Avalonia.Data;
#nullable enable
namespace Avalonia
{
/// <summary>
@ -18,7 +20,7 @@ namespace Avalonia
/// Whether the property is interested in data validation.
/// </param>
public DirectPropertyMetadata(
TValue unsetValue = default(TValue),
TValue unsetValue = default!,
BindingMode defaultBindingMode = BindingMode.Default,
bool? enableDataValidation = null)
: base(defaultBindingMode)
@ -44,7 +46,7 @@ namespace Avalonia
public bool? EnableDataValidation { get; private set; }
/// <inheritdoc/>
object IDirectPropertyMetadata.UnsetValue => UnsetValue;
object? IDirectPropertyMetadata.UnsetValue => UnsetValue;
/// <inheritdoc/>
public override void Merge(AvaloniaPropertyMetadata baseMetadata, AvaloniaProperty property)

2
src/Avalonia.Base/EnumExtensions.cs

@ -1,6 +1,8 @@
using System;
using System.Runtime.CompilerServices;
#nullable enable
namespace Avalonia
{
/// <summary>

4
src/Avalonia.Base/IDescription.cs

@ -1,3 +1,5 @@
#nullable enable
namespace Avalonia
{
/// <summary>
@ -11,6 +13,6 @@ namespace Avalonia
/// <value>
/// The description of the object.
/// </value>
string Description { get; }
string? Description { get; }
}
}

6
src/Avalonia.Base/IDirectPropertyAccessor.cs

@ -1,5 +1,7 @@
using System;
#nullable enable
namespace Avalonia
{
/// <summary>
@ -23,13 +25,13 @@ namespace Avalonia
/// </summary>
/// <param name="instance">The instance.</param>
/// <returns>The property value.</returns>
object GetValue(IAvaloniaObject instance);
object? GetValue(IAvaloniaObject instance);
/// <summary>
/// Sets the value of the property on the instance.
/// </summary>
/// <param name="instance">The instance.</param>
/// <param name="value">The value.</param>
void SetValue(IAvaloniaObject instance, object value);
void SetValue(IAvaloniaObject instance, object? value);
}
}

6
src/Avalonia.Base/IDirectPropertyMetadata.cs

@ -1,3 +1,5 @@
#nullable enable
namespace Avalonia
{
/// <summary>
@ -8,11 +10,11 @@ namespace Avalonia
/// <summary>
/// Gets the to use when the property is set to <see cref="AvaloniaProperty.UnsetValue"/>.
/// </summary>
object UnsetValue { get; }
object? UnsetValue { get; }
/// <summary>
/// Gets a value indicating whether the property is interested in data validation.
/// </summary>
bool? EnableDataValidation { get; }
}
}
}

4
src/Avalonia.Base/IStyledPropertyAccessor.cs

@ -1,5 +1,7 @@
using System;
#nullable enable
namespace Avalonia
{
/// <summary>
@ -14,6 +16,6 @@ namespace Avalonia
/// <returns>
/// The default value.
/// </returns>
object GetDefaultValue(Type type);
object? GetDefaultValue(Type type);
}
}

4
src/Avalonia.Base/IStyledPropertyMetadata.cs

@ -1,3 +1,5 @@
#nullable enable
namespace Avalonia
{
/// <summary>
@ -8,6 +10,6 @@ namespace Avalonia
/// <summary>
/// Gets the default value for the property.
/// </summary>
object DefaultValue { get; }
object? DefaultValue { get; }
}
}

4
src/Avalonia.Base/Reactive/AvaloniaPropertyBindingObservable.cs

@ -28,7 +28,7 @@ namespace Avalonia.Reactive
{
if (_target.TryGetTarget(out var target))
{
_value = (T)target.GetValue(_property);
_value = (T)target.GetValue(_property)!;
target.PropertyChanged += PropertyChanged;
}
}
@ -66,7 +66,7 @@ namespace Avalonia.Reactive
if (!Equals(newValue, _value))
{
_value = (T)newValue;
_value = (T)newValue!;
PublishNext(_value);
}
}

10
src/Avalonia.Base/Reactive/TypedBindingAdapter.cs

@ -7,24 +7,24 @@ using Avalonia.Logging;
namespace Avalonia.Reactive
{
internal class TypedBindingAdapter<T> : SingleSubscriberObservableBase<BindingValue<T>>,
IObserver<BindingValue<object>>
IObserver<BindingValue<object?>>
{
private readonly IAvaloniaObject _target;
private readonly AvaloniaProperty<T> _property;
private readonly IObservable<BindingValue<object>> _source;
private readonly IObservable<BindingValue<object?>> _source;
private IDisposable? _subscription;
public TypedBindingAdapter(
IAvaloniaObject target,
AvaloniaProperty<T> property,
IObservable<BindingValue<object>> source)
IObservable<BindingValue<object?>> source)
{
_target = target;
_property = property;
_source = source;
}
public void OnNext(BindingValue<object> value)
public void OnNext(BindingValue<object?> value)
{
try
{
@ -49,7 +49,7 @@ namespace Avalonia.Reactive
public static IObservable<BindingValue<T>> Create(
IAvaloniaObject target,
AvaloniaProperty<T> property,
IObservable<BindingValue<object>> source)
IObservable<BindingValue<object?>> source)
{
return source is IObservable<BindingValue<T>> result ?
result :

6
src/Avalonia.Base/StyledProperty.cs

@ -1,5 +1,7 @@
using System;
#nullable enable
namespace Avalonia
{
/// <summary>
@ -21,8 +23,8 @@ namespace Avalonia
Type ownerType,
StyledPropertyMetadata<TValue> metadata,
bool inherits = false,
Func<TValue, bool> validate = null,
Action<IAvaloniaObject, bool> notifying = null)
Func<TValue, bool>? validate = null,
Action<IAvaloniaObject, bool>? notifying = null)
: base(name, ownerType, metadata, inherits, validate, notifying)
{
}

40
src/Avalonia.Base/StyledPropertyBase.cs

@ -4,6 +4,8 @@ using Avalonia.Data;
using Avalonia.Reactive;
using Avalonia.Utilities;
#nullable enable
namespace Avalonia
{
/// <summary>
@ -27,18 +29,10 @@ namespace Avalonia
Type ownerType,
StyledPropertyMetadata<TValue> metadata,
bool inherits = false,
Func<TValue, bool> validate = null,
Action<IAvaloniaObject, bool> notifying = null)
Func<TValue, bool>? validate = null,
Action<IAvaloniaObject, bool>? notifying = null)
: base(name, ownerType, metadata, notifying)
{
Contract.Requires<ArgumentNullException>(name != null);
Contract.Requires<ArgumentNullException>(ownerType != null);
if (name.Contains("."))
{
throw new ArgumentException("'name' may not contain periods.");
}
_inherits = inherits;
ValidateValue = validate;
HasCoercion |= metadata.CoerceValue != null;
@ -72,7 +66,7 @@ namespace Avalonia
/// <summary>
/// Gets the value validation callback for the property.
/// </summary>
public Func<TValue, bool> ValidateValue { get; }
public Func<TValue, bool>? ValidateValue { get; }
/// <summary>
/// Gets a value indicating whether this property has any value coercion callbacks defined
@ -99,8 +93,6 @@ namespace Avalonia
/// <returns>The default value.</returns>
public TValue GetDefaultValue(Type type)
{
Contract.Requires<ArgumentNullException>(type != null);
return GetMetadata(type).DefaultValue;
}
@ -113,6 +105,7 @@ namespace Avalonia
/// </returns>
public new StyledPropertyMetadata<TValue> GetMetadata(Type type)
{
_ = type ?? throw new ArgumentNullException(nameof(type));
return (StyledPropertyMetadata<TValue>)base.GetMetadata(type);
}
@ -183,7 +176,7 @@ namespace Avalonia
}
/// <inheritdoc/>
object IStyledPropertyAccessor.GetDefaultValue(Type type) => GetDefaultBoxedValue(type);
object? IStyledPropertyAccessor.GetDefaultValue(Type type) => GetDefaultBoxedValue(type);
/// <inheritdoc/>
internal override void RouteClearValue(IAvaloniaObject o)
@ -192,22 +185,22 @@ namespace Avalonia
}
/// <inheritdoc/>
internal override object RouteGetValue(IAvaloniaObject o)
internal override object? RouteGetValue(IAvaloniaObject o)
{
return o.GetValue<TValue>(this);
}
/// <inheritdoc/>
internal override object RouteGetBaseValue(IAvaloniaObject o, BindingPriority maxPriority)
internal override object? RouteGetBaseValue(IAvaloniaObject o, BindingPriority maxPriority)
{
var value = o.GetBaseValue<TValue>(this, maxPriority);
return value.HasValue ? value.Value : AvaloniaProperty.UnsetValue;
}
/// <inheritdoc/>
internal override IDisposable RouteSetValue(
internal override IDisposable? RouteSetValue(
IAvaloniaObject o,
object value,
object? value,
BindingPriority priority)
{
var v = TryConvert(value);
@ -222,7 +215,7 @@ namespace Avalonia
}
else if (v.HasError)
{
throw v.Error;
throw v.Error!;
}
return null;
@ -231,7 +224,7 @@ namespace Avalonia
/// <inheritdoc/>
internal override IDisposable RouteBind(
IAvaloniaObject o,
IObservable<BindingValue<object>> source,
IObservable<BindingValue<object?>> source,
BindingPriority priority)
{
var adapter = TypedBindingAdapter<TValue>.Create(o, this, source);
@ -241,15 +234,14 @@ namespace Avalonia
/// <inheritdoc/>
internal override void RouteInheritanceParentChanged(
AvaloniaObject o,
IAvaloniaObject oldParent)
IAvaloniaObject? oldParent)
{
o.InheritanceParentChanged(this, oldParent);
}
private object GetDefaultBoxedValue(Type type)
private object? GetDefaultBoxedValue(Type type)
{
Contract.Requires<ArgumentNullException>(type != null);
_ = type ?? throw new ArgumentNullException(nameof(type));
return GetMetadata(type).DefaultValue;
}

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

@ -1,6 +1,8 @@
using System;
using Avalonia.Data;
#nullable enable
namespace Avalonia
{
/// <summary>
@ -19,7 +21,7 @@ namespace Avalonia
public StyledPropertyMetadata(
Optional<TValue> defaultValue = default,
BindingMode defaultBindingMode = BindingMode.Default,
Func<IAvaloniaObject, TValue, TValue> coerce = null)
Func<IAvaloniaObject, TValue, TValue>? coerce = null)
: base(defaultBindingMode)
{
_defaultValue = defaultValue;
@ -29,14 +31,14 @@ namespace Avalonia
/// <summary>
/// Gets the default value for the property.
/// </summary>
public TValue DefaultValue => _defaultValue.GetValueOrDefault();
public TValue DefaultValue => _defaultValue.GetValueOrDefault()!;
/// <summary>
/// Gets the value coercion callback, if any.
/// </summary>
public Func<IAvaloniaObject, TValue, TValue> CoerceValue { get; private set; }
public Func<IAvaloniaObject, TValue, TValue>? CoerceValue { get; private set; }
object IStyledPropertyMetadata.DefaultValue => DefaultValue;
object? IStyledPropertyMetadata.DefaultValue => DefaultValue;
/// <inheritdoc/>
public override void Merge(AvaloniaPropertyMetadata baseMetadata, AvaloniaProperty property)

1
src/Avalonia.Input/Avalonia.Input.csproj

@ -2,7 +2,6 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Nullable>Enable</Nullable>
<WarningsAsErrors>CS8600;CS8602;CS8603</WarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Avalonia.Base\Metadata\NullableAttributes.cs" Link="NullableAttributes.cs" />

8
src/Avalonia.Styling/Styling/Activators/PropertyEqualsActivator.cs

@ -7,7 +7,7 @@ namespace Avalonia.Styling.Activators
/// <summary>
/// An <see cref="IStyleActivator"/> which listens to a property value on a control.
/// </summary>
internal class PropertyEqualsActivator : StyleActivatorBase, IObserver<object>
internal class PropertyEqualsActivator : StyleActivatorBase, IObserver<object?>
{
private readonly IStyleable _control;
private readonly AvaloniaProperty _property;
@ -31,8 +31,8 @@ namespace Avalonia.Styling.Activators
protected override void Deinitialize() => _subscription?.Dispose();
void IObserver<object>.OnCompleted() { }
void IObserver<object>.OnError(Exception error) { }
void IObserver<object>.OnNext(object value) => PublishNext(Equals(value, _value));
void IObserver<object?>.OnCompleted() { }
void IObserver<object?>.OnError(Exception error) { }
void IObserver<object?>.OnNext(object value) => PublishNext(Equals(value, _value));
}
}

10
src/Markup/Avalonia.Markup/Data/TemplateBinding.cs

@ -10,10 +10,10 @@ namespace Avalonia.Data
/// <summary>
/// A XAML binding to a property on a control's templated parent.
/// </summary>
public class TemplateBinding : SingleSubscriberObservableBase<object>,
public class TemplateBinding : SingleSubscriberObservableBase<object?>,
IBinding,
IDescription,
ISubject<object>,
ISubject<object?>,
ISetterValue
{
private bool _isSetterValue;
@ -88,10 +88,10 @@ namespace Avalonia.Data
/// <inheritdoc/>
public string Description => "TemplateBinding: " + Property;
void IObserver<object>.OnCompleted() => throw new NotImplementedException();
void IObserver<object>.OnError(Exception error) => throw new NotImplementedException();
void IObserver<object?>.OnCompleted() => throw new NotImplementedException();
void IObserver<object?>.OnError(Exception error) => throw new NotImplementedException();
void IObserver<object>.OnNext(object value)
void IObserver<object?>.OnNext(object? value)
{
if (_target.TemplatedParent != null && Property != null)
{

Loading…
Cancel
Save