Browse Source

Merge pull request #7082 from AvaloniaUI/fixes/avalonia-collections-nullability

Add nullable annotations to Avalonia.Collections.
release/0.10.11-rc.2
Max Katz 4 years ago
committed by Dan Walmsley
parent
commit
15a406296c
  1. 6
      src/Avalonia.Base/Collections/AvaloniaDictionary.cs
  2. 61
      src/Avalonia.Base/Collections/AvaloniaList.cs
  3. 2
      src/Avalonia.Base/Collections/AvaloniaListConverter.cs
  4. 4
      src/Avalonia.Base/Collections/AvaloniaListExtensions.cs
  5. 2
      src/Avalonia.Base/Collections/IAvaloniaList.cs
  6. 2
      src/Avalonia.Base/Collections/IAvaloniaReadOnlyList.cs
  7. 12
      src/Avalonia.Base/Collections/NotifyCollectionChangedExtensions.cs
  8. 2
      src/Avalonia.Base/Collections/Pooled/ClearMode.cs
  9. 2
      src/Avalonia.Base/Collections/Pooled/ICollectionDebugView.cs
  10. 2
      src/Avalonia.Base/Collections/Pooled/IReadOnlyPooledList.cs
  11. 49
      src/Avalonia.Base/Collections/Pooled/PooledList.cs
  12. 22
      src/Avalonia.Base/Collections/Pooled/PooledStack.cs
  13. 2
      src/Avalonia.Base/Collections/Pooled/StackDebugView.cs
  14. 66
      src/Avalonia.Base/Collections/Pooled/ThrowHelper.cs
  15. 3
      src/Avalonia.Styling/Controls/ResourceDictionary.cs

6
src/Avalonia.Base/Collections/AvaloniaDictionary.cs

@ -6,6 +6,8 @@ using System.ComponentModel;
using System.Linq;
using Avalonia.Data.Core;
#nullable enable
namespace Avalonia.Collections
{
/// <summary>
@ -31,12 +33,12 @@ namespace Avalonia.Collections
/// <summary>
/// Occurs when the collection changes.
/// </summary>
public event NotifyCollectionChangedEventHandler CollectionChanged;
public event NotifyCollectionChangedEventHandler? CollectionChanged;
/// <summary>
/// Raised when a property on the collection changes.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
public event PropertyChangedEventHandler? PropertyChanged;
/// <inheritdoc/>
public int Count => _inner.Count;

61
src/Avalonia.Base/Collections/AvaloniaList.cs

@ -6,6 +6,8 @@ using System.ComponentModel;
using System.Linq;
using Avalonia.Diagnostics;
#nullable enable
namespace Avalonia.Collections
{
/// <summary>
@ -53,7 +55,7 @@ namespace Avalonia.Collections
public class AvaloniaList<T> : IAvaloniaList<T>, IList, INotifyCollectionChangedDebug
{
private readonly List<T> _inner;
private NotifyCollectionChangedEventHandler _collectionChanged;
private NotifyCollectionChangedEventHandler? _collectionChanged;
/// <summary>
/// Initializes a new instance of the <see cref="AvaloniaList{T}"/> class.
@ -102,7 +104,7 @@ namespace Avalonia.Collections
/// <summary>
/// Raised when a property on the collection changes.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
public event PropertyChangedEventHandler? PropertyChanged;
/// <summary>
/// Gets the number of items in the collection.
@ -118,7 +120,7 @@ namespace Avalonia.Collections
/// Gets or sets a validation routine that can be used to validate items before they are
/// added.
/// </summary>
public Action<T> Validate { get; set; }
public Action<T>? Validate { get; set; }
/// <inheritdoc/>
bool IList.IsFixedSize => false;
@ -133,7 +135,7 @@ namespace Avalonia.Collections
bool ICollection.IsSynchronized => false;
/// <inheritdoc/>
object ICollection.SyncRoot => null;
object? ICollection.SyncRoot => null;
/// <inheritdoc/>
bool ICollection<T>.IsReadOnly => false;
@ -178,10 +180,10 @@ namespace Avalonia.Collections
/// </summary>
/// <param name="index">The index.</param>
/// <returns>The item.</returns>
object IList.this[int index]
object? IList.this[int index]
{
get { return this[index]; }
set { this[index] = (T)value; }
set { this[index] = (T)value!; }
}
/// <summary>
@ -318,7 +320,7 @@ namespace Avalonia.Collections
/// <param name="items">The items.</param>
public virtual void InsertRange(int index, IEnumerable<T> items)
{
Contract.Requires<ArgumentNullException>(items != null);
_ = items ?? throw new ArgumentNullException(nameof(items));
bool willRaiseCollectionChanged = _collectionChanged != null;
bool hasValidation = Validate != null;
@ -333,7 +335,7 @@ namespace Avalonia.Collections
{
foreach (T item in collection)
{
Validate(item);
Validate!(item);
}
}
@ -354,7 +356,7 @@ namespace Avalonia.Collections
if (hasValidation)
{
Validate(item);
Validate!(item);
}
_inner.Insert(insertIndex++, item);
@ -372,7 +374,7 @@ namespace Avalonia.Collections
if (en.MoveNext())
{
// Avoid allocating list for collection notification if there is no event subscriptions.
List<T> notificationItems = willRaiseCollectionChanged ?
List<T>? notificationItems = willRaiseCollectionChanged ?
new List<T>() :
null;
@ -384,19 +386,17 @@ namespace Avalonia.Collections
if (hasValidation)
{
Validate(item);
Validate!(item);
}
_inner.Insert(insertIndex++, item);
if (willRaiseCollectionChanged)
{
notificationItems.Add(item);
}
notificationItems?.Add(item);
} while (en.MoveNext());
NotifyAdd(notificationItems, index);
if (notificationItems is not null)
NotifyAdd(notificationItems, index);
}
}
}
@ -501,7 +501,7 @@ namespace Avalonia.Collections
/// <param name="items">The items.</param>
public virtual void RemoveAll(IEnumerable<T> items)
{
Contract.Requires<ArgumentNullException>(items != null);
_ = items ?? throw new ArgumentNullException(nameof(items));
foreach (var i in items)
{
@ -537,17 +537,17 @@ namespace Avalonia.Collections
}
/// <inheritdoc/>
int IList.Add(object value)
int IList.Add(object? value)
{
int index = Count;
Add((T)value);
Add((T)value!);
return index;
}
/// <inheritdoc/>
bool IList.Contains(object value)
bool IList.Contains(object? value)
{
return Contains((T)value);
return Contains((T)value!);
}
/// <inheritdoc/>
@ -557,21 +557,21 @@ namespace Avalonia.Collections
}
/// <inheritdoc/>
int IList.IndexOf(object value)
int IList.IndexOf(object? value)
{
return IndexOf((T)value);
return IndexOf((T)value!);
}
/// <inheritdoc/>
void IList.Insert(int index, object value)
void IList.Insert(int index, object? value)
{
Insert(index, (T)value);
Insert(index, (T)value!);
}
/// <inheritdoc/>
void IList.Remove(object value)
void IList.Remove(object? value)
{
Remove((T)value);
Remove((T)value!);
}
/// <inheritdoc/>
@ -631,8 +631,7 @@ namespace Avalonia.Collections
// We can't cast array of value type to object[], so we don't support
// widening of primitive types here.
//
object[] objects = array as object[];
if (objects == null)
if (array is not object?[] objects)
{
throw new ArgumentException("Invalid array type");
}
@ -653,7 +652,7 @@ namespace Avalonia.Collections
}
/// <inheritdoc/>
Delegate[] INotifyCollectionChangedDebug.GetCollectionChangedSubscribers() => _collectionChanged?.GetInvocationList();
Delegate[]? INotifyCollectionChangedDebug.GetCollectionChangedSubscribers() => _collectionChanged?.GetInvocationList();
/// <summary>
/// Raises the <see cref="CollectionChanged"/> event with an add action.
@ -752,7 +751,7 @@ namespace Avalonia.Collections
public T Current => _innerEnumerator.Current;
object IEnumerator.Current => Current;
object? IEnumerator.Current => Current;
public void Dispose()
{

2
src/Avalonia.Base/Collections/AvaloniaListConverter.cs

@ -3,6 +3,8 @@ using System.ComponentModel;
using System.Globalization;
using Avalonia.Utilities;
#nullable enable
namespace Avalonia.Collections
{
/// <summary>

4
src/Avalonia.Base/Collections/AvaloniaListExtensions.cs

@ -5,6 +5,8 @@ using System.Collections.Specialized;
using System.ComponentModel;
using System.Reactive.Disposables;
#nullable enable
namespace Avalonia.Collections
{
/// <summary>
@ -194,7 +196,7 @@ namespace Avalonia.Collections
tracked.Remove(inpc);
}
},
null);
() => throw new NotSupportedException("Collection reset not supported."));
return Disposable.Create(() =>
{

2
src/Avalonia.Base/Collections/IAvaloniaList.cs

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

2
src/Avalonia.Base/Collections/IAvaloniaReadOnlyList.cs

@ -2,6 +2,8 @@ using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
#nullable enable
namespace Avalonia.Collections
{
/// <summary>

12
src/Avalonia.Base/Collections/NotifyCollectionChangedExtensions.cs

@ -4,6 +4,8 @@ using System.Reactive.Linq;
using Avalonia.Reactive;
using Avalonia.Utilities;
#nullable enable
namespace Avalonia.Collections
{
public static class NotifyCollectionChangedExtensions
@ -16,7 +18,7 @@ namespace Avalonia.Collections
public static IObservable<NotifyCollectionChangedEventArgs> GetWeakCollectionChangedObservable(
this INotifyCollectionChanged collection)
{
Contract.Requires<ArgumentNullException>(collection != null);
_ = collection ?? throw new ArgumentNullException(nameof(collection));
return new WeakCollectionChangedObservable(new WeakReference<INotifyCollectionChanged>(collection));
}
@ -33,8 +35,8 @@ namespace Avalonia.Collections
this INotifyCollectionChanged collection,
NotifyCollectionChangedEventHandler handler)
{
Contract.Requires<ArgumentNullException>(collection != null);
Contract.Requires<ArgumentNullException>(handler != null);
_ = collection ?? throw new ArgumentNullException(nameof(collection));
_ = handler ?? throw new ArgumentNullException(nameof(handler));
return collection.GetWeakCollectionChangedObservable()
.Subscribe(e => handler(collection, e));
@ -52,8 +54,8 @@ namespace Avalonia.Collections
this INotifyCollectionChanged collection,
Action<NotifyCollectionChangedEventArgs> handler)
{
Contract.Requires<ArgumentNullException>(collection != null);
Contract.Requires<ArgumentNullException>(handler != null);
_ = collection ?? throw new ArgumentNullException(nameof(collection));
_ = handler ?? throw new ArgumentNullException(nameof(handler));
return collection.GetWeakCollectionChangedObservable().Subscribe(handler);
}

2
src/Avalonia.Base/Collections/Pooled/ClearMode.cs

@ -1,6 +1,8 @@
// This source file is adapted from the Collections.Pooled.
// (https://github.com/jtmueller/Collections.Pooled/tree/master/Collections.Pooled/)
#nullable enable
namespace Avalonia.Collections.Pooled
{
/// <summary>

2
src/Avalonia.Base/Collections/Pooled/ICollectionDebugView.cs

@ -6,6 +6,8 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
#nullable enable
namespace Avalonia.Collections.Pooled
{
internal sealed class ICollectionDebugView<T>

2
src/Avalonia.Base/Collections/Pooled/IReadOnlyPooledList.cs

@ -4,6 +4,8 @@
using System;
using System.Collections.Generic;
#nullable enable
namespace Avalonia.Collections.Pooled
{
/// <summary>

49
src/Avalonia.Base/Collections/Pooled/PooledList.cs

@ -8,10 +8,13 @@ using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Threading;
#nullable enable
namespace Avalonia.Collections.Pooled
{
/// <summary>
@ -38,7 +41,7 @@ namespace Avalonia.Collections.Pooled
[NonSerialized]
private ArrayPool<T> _pool;
[NonSerialized]
private object _syncRoot;
private object? _syncRoot;
private T[] _items; // Do not rename (binary serialization)
private int _size; // Do not rename (binary serialization)
@ -375,7 +378,7 @@ namespace Avalonia.Collections.Pooled
{
if (_syncRoot == null)
{
Interlocked.CompareExchange<object>(ref _syncRoot, new object(), null);
Interlocked.CompareExchange<object?>(ref _syncRoot, new object(), null);
}
return _syncRoot;
}
@ -407,14 +410,14 @@ namespace Avalonia.Collections.Pooled
}
}
private static bool IsCompatibleObject(object value)
private static bool IsCompatibleObject(object? value)
{
// Non-null values are fine. Only accept nulls if T is a class or Nullable<U>.
// Note that default(T) is not equal to null for value types except when T is Nullable<U>.
return ((value is T) || (value == null && default(T) == null));
}
object IList.this[int index]
object? IList.this[int index]
{
get
{
@ -426,7 +429,7 @@ namespace Avalonia.Collections.Pooled
try
{
this[index] = (T)value;
this[index] = (T)value!;
}
catch (InvalidCastException)
{
@ -466,13 +469,13 @@ namespace Avalonia.Collections.Pooled
_items[size] = item;
}
int IList.Add(object item)
int IList.Add(object? item)
{
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(item, ExceptionArgument.item);
try
{
Add((T)item);
Add((T)item!);
}
catch (InvalidCastException)
{
@ -545,7 +548,7 @@ namespace Avalonia.Collections.Pooled
/// the search value should be inserted into the list in order for the list
/// to remain sorted.
/// </para></remarks>
public int BinarySearch(int index, int count, T item, IComparer<T> comparer)
public int BinarySearch(int index, int count, T item, IComparer<T>? comparer)
{
if (index < 0)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
@ -608,11 +611,11 @@ namespace Avalonia.Collections.Pooled
return _size != 0 && IndexOf(item) != -1;
}
bool IList.Contains(object item)
bool IList.Contains(object? item)
{
if (IsCompatibleObject(item))
{
return Contains((T)item);
return Contains((T)item!);
}
return false;
}
@ -693,7 +696,7 @@ namespace Avalonia.Collections.Pooled
public bool Exists(Func<T, bool> match)
=> FindIndex(match) != -1;
public bool TryFind(Func<T, bool> match, out T result)
public bool TryFind(Func<T, bool> match, [MaybeNullWhen(false)] out T result)
{
if (match == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
@ -753,7 +756,7 @@ namespace Avalonia.Collections.Pooled
return -1;
}
public bool TryFindLast(Func<T, bool> match, out T result)
public bool TryFindLast(Func<T, bool> match, [MaybeNullWhen(false)] out T result)
{
if (match is null)
{
@ -886,11 +889,11 @@ namespace Avalonia.Collections.Pooled
public int IndexOf(T item)
=> Array.IndexOf(_items, item, 0, _size);
int IList.IndexOf(object item)
int IList.IndexOf(object? item)
{
if (IsCompatibleObject(item))
{
return IndexOf((T)item);
return IndexOf((T)item!);
}
return -1;
}
@ -947,13 +950,13 @@ namespace Avalonia.Collections.Pooled
_version++;
}
void IList.Insert(int index, object item)
void IList.Insert(int index, object? item)
{
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(item, ExceptionArgument.item);
try
{
Insert(index, (T)item);
Insert(index, (T)item!);
}
catch (InvalidCastException)
{
@ -1155,11 +1158,11 @@ namespace Avalonia.Collections.Pooled
return false;
}
void IList.Remove(object item)
void IList.Remove(object? item)
{
if (IsCompatibleObject(item))
{
Remove((T)item);
Remove((T)item!);
}
}
@ -1225,7 +1228,7 @@ namespace Avalonia.Collections.Pooled
if (_clearOnFree)
{
// Clear the removed element so that the gc can reclaim the reference.
_items[_size] = default;
_items[_size] = default!;
}
}
@ -1315,7 +1318,7 @@ namespace Avalonia.Collections.Pooled
///
/// This method uses the Array.Sort method to sort the elements.
/// </summary>
public void Sort(int index, int count, IComparer<T> comparer)
public void Sort(int index, int count, IComparer<T>? comparer)
{
if (index < 0)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
@ -1452,7 +1455,7 @@ namespace Avalonia.Collections.Pooled
private readonly PooledList<T> _list;
private int _index;
private readonly int _version;
private T _current;
private T? _current;
internal Enumerator(PooledList<T> list)
{
@ -1491,9 +1494,9 @@ namespace Avalonia.Collections.Pooled
return false;
}
public T Current => _current;
public T Current => _current!;
object IEnumerator.Current
object? IEnumerator.Current
{
get
{

22
src/Avalonia.Base/Collections/Pooled/PooledStack.cs

@ -20,6 +20,8 @@ using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Threading;
#nullable enable
namespace Avalonia.Collections.Pooled
{
/// <summary>
@ -34,7 +36,7 @@ namespace Avalonia.Collections.Pooled
[NonSerialized]
private ArrayPool<T> _pool;
[NonSerialized]
private object _syncRoot;
private object? _syncRoot;
private T[] _array; // Storage for stack elements. Do not rename (binary serialization)
private int _size; // Number of items in the stack. Do not rename (binary serialization)
@ -237,7 +239,7 @@ namespace Avalonia.Collections.Pooled
{
if (_syncRoot == null)
{
Interlocked.CompareExchange<object>(ref _syncRoot, new object(), null);
Interlocked.CompareExchange<object?>(ref _syncRoot, new object(), null);
}
return _syncRoot;
}
@ -456,7 +458,7 @@ namespace Avalonia.Collections.Pooled
return array[size];
}
public bool TryPeek(out T result)
public bool TryPeek([MaybeNullWhen(false)] out T result)
{
int size = _size - 1;
T[] array = _array;
@ -492,12 +494,12 @@ namespace Avalonia.Collections.Pooled
T item = array[size];
if (_clearOnFree)
{
array[size] = default; // Free memory quicker.
array[size] = default!; // Free memory quicker.
}
return item;
}
public bool TryPop(out T result)
public bool TryPop([MaybeNullWhen(false)] out T result)
{
int size = _size - 1;
T[] array = _array;
@ -513,7 +515,7 @@ namespace Avalonia.Collections.Pooled
result = array[size];
if (_clearOnFree)
{
array[size] = default; // Free memory quicker.
array[size] = default!; // Free memory quicker.
}
return true;
}
@ -574,7 +576,7 @@ namespace Avalonia.Collections.Pooled
throw new InvalidOperationException("Stack was empty.");
}
private void ReturnArray(T[] replaceWith = null)
private void ReturnArray(T[]? replaceWith = null)
{
if (_array?.Length > 0)
{
@ -625,7 +627,7 @@ namespace Avalonia.Collections.Pooled
private readonly PooledStack<T> _stack;
private readonly int _version;
private int _index;
private T _currentElement;
private T? _currentElement;
internal Enumerator(PooledStack<T> stack)
{
@ -672,7 +674,7 @@ namespace Avalonia.Collections.Pooled
{
if (_index < 0)
ThrowEnumerationNotStartedOrEnded();
return _currentElement;
return _currentElement!;
}
}
@ -682,7 +684,7 @@ namespace Avalonia.Collections.Pooled
throw new InvalidOperationException(_index == -2 ? "Enumeration was not started." : "Enumeration has ended.");
}
object IEnumerator.Current
object? IEnumerator.Current
{
get { return Current; }
}

2
src/Avalonia.Base/Collections/Pooled/StackDebugView.cs

@ -5,6 +5,8 @@
using System;
using System.Diagnostics;
#nullable enable
namespace Avalonia.Collections.Pooled
{
internal sealed class StackDebugView<T>

66
src/Avalonia.Base/Collections/Pooled/ThrowHelper.cs

@ -38,108 +38,128 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
#nullable enable
namespace Avalonia.Collections.Pooled
{
internal static class ThrowHelper
{
[DoesNotReturn]
internal static void ThrowArrayTypeMismatchException()
{
throw new ArrayTypeMismatchException();
}
[DoesNotReturn]
internal static void ThrowIndexOutOfRangeException()
{
throw new IndexOutOfRangeException();
}
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeException()
{
throw new ArgumentOutOfRangeException();
}
[DoesNotReturn]
internal static void ThrowArgumentException_DestinationTooShort()
{
throw new ArgumentException("Destination too short.");
}
[DoesNotReturn]
internal static void ThrowArgumentException_OverlapAlignmentMismatch()
{
throw new ArgumentException("Overlap alignment mismatch.");
}
[DoesNotReturn]
internal static void ThrowArgumentOutOfRange_IndexException()
{
throw GetArgumentOutOfRangeException(ExceptionArgument.index,
ExceptionResource.ArgumentOutOfRange_Index);
}
[DoesNotReturn]
internal static void ThrowIndexArgumentOutOfRange_NeedNonNegNumException()
{
throw GetArgumentOutOfRangeException(ExceptionArgument.index,
ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
[DoesNotReturn]
internal static void ThrowValueArgumentOutOfRange_NeedNonNegNumException()
{
throw GetArgumentOutOfRangeException(ExceptionArgument.value,
ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
[DoesNotReturn]
internal static void ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum()
{
throw GetArgumentOutOfRangeException(ExceptionArgument.length,
ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
[DoesNotReturn]
internal static void ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index()
{
throw GetArgumentOutOfRangeException(ExceptionArgument.startIndex,
ExceptionResource.ArgumentOutOfRange_Index);
}
[DoesNotReturn]
internal static void ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count()
{
throw GetArgumentOutOfRangeException(ExceptionArgument.count,
ExceptionResource.ArgumentOutOfRange_Count);
}
[DoesNotReturn]
internal static void ThrowWrongKeyTypeArgumentException<T>(T key, Type targetType)
{
// Generic key to move the boxing to the right hand side of throw
throw GetWrongKeyTypeArgumentException((object)key, targetType);
throw GetWrongKeyTypeArgumentException((object?)key, targetType);
}
[DoesNotReturn]
internal static void ThrowWrongValueTypeArgumentException<T>(T value, Type targetType)
{
// Generic key to move the boxing to the right hand side of throw
throw GetWrongValueTypeArgumentException((object)value, targetType);
throw GetWrongValueTypeArgumentException((object?)value, targetType);
}
private static ArgumentException GetAddingDuplicateWithKeyArgumentException(object key)
private static ArgumentException GetAddingDuplicateWithKeyArgumentException(object? key)
{
return new ArgumentException($"Error adding duplicate with key: {key}.");
}
[DoesNotReturn]
internal static void ThrowAddingDuplicateWithKeyArgumentException<T>(T key)
{
// Generic key to move the boxing to the right hand side of throw
throw GetAddingDuplicateWithKeyArgumentException((object)key);
throw GetAddingDuplicateWithKeyArgumentException((object?)key);
}
[DoesNotReturn]
internal static void ThrowKeyNotFoundException<T>(T key)
{
// Generic key to move the boxing to the right hand side of throw
throw GetKeyNotFoundException((object)key);
throw GetKeyNotFoundException((object?)key);
}
[DoesNotReturn]
internal static void ThrowArgumentException(ExceptionResource resource)
{
throw GetArgumentException(resource);
}
[DoesNotReturn]
internal static void ThrowArgumentException(ExceptionResource resource, ExceptionArgument argument)
{
throw GetArgumentException(resource, argument);
@ -150,141 +170,169 @@ namespace Avalonia.Collections.Pooled
return new ArgumentNullException(GetArgumentName(argument));
}
[DoesNotReturn]
internal static void ThrowArgumentNullException(ExceptionArgument argument)
{
throw GetArgumentNullException(argument);
}
[DoesNotReturn]
internal static void ThrowArgumentNullException(ExceptionResource resource)
{
throw new ArgumentNullException(GetResourceString(resource));
}
[DoesNotReturn]
internal static void ThrowArgumentNullException(ExceptionArgument argument, ExceptionResource resource)
{
throw new ArgumentNullException(GetArgumentName(argument), GetResourceString(resource));
}
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument)
{
throw new ArgumentOutOfRangeException(GetArgumentName(argument));
}
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
{
throw GetArgumentOutOfRangeException(argument, resource);
}
[DoesNotReturn]
internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument, int paramNumber, ExceptionResource resource)
{
throw GetArgumentOutOfRangeException(argument, paramNumber, resource);
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException(ExceptionResource resource)
{
throw GetInvalidOperationException(resource);
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException(ExceptionResource resource, Exception e)
{
throw new InvalidOperationException(GetResourceString(resource), e);
}
[DoesNotReturn]
internal static void ThrowSerializationException(ExceptionResource resource)
{
throw new SerializationException(GetResourceString(resource));
}
[DoesNotReturn]
internal static void ThrowSecurityException(ExceptionResource resource)
{
throw new System.Security.SecurityException(GetResourceString(resource));
}
[DoesNotReturn]
internal static void ThrowRankException(ExceptionResource resource)
{
throw new RankException(GetResourceString(resource));
}
[DoesNotReturn]
internal static void ThrowNotSupportedException(ExceptionResource resource)
{
throw new NotSupportedException(GetResourceString(resource));
}
[DoesNotReturn]
internal static void ThrowUnauthorizedAccessException(ExceptionResource resource)
{
throw new UnauthorizedAccessException(GetResourceString(resource));
}
[DoesNotReturn]
internal static void ThrowObjectDisposedException(string objectName, ExceptionResource resource)
{
throw new ObjectDisposedException(objectName, GetResourceString(resource));
}
[DoesNotReturn]
internal static void ThrowObjectDisposedException(ExceptionResource resource)
{
throw new ObjectDisposedException(null, GetResourceString(resource));
}
[DoesNotReturn]
internal static void ThrowNotSupportedException()
{
throw new NotSupportedException();
}
[DoesNotReturn]
internal static void ThrowAggregateException(List<Exception> exceptions)
{
throw new AggregateException(exceptions);
}
[DoesNotReturn]
internal static void ThrowOutOfMemoryException()
{
throw new OutOfMemoryException();
}
[DoesNotReturn]
internal static void ThrowArgumentException_Argument_InvalidArrayType()
{
throw new ArgumentException("Invalid array type.");
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException_InvalidOperation_EnumNotStarted()
{
throw new InvalidOperationException("Enumeration has not started.");
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException_InvalidOperation_EnumEnded()
{
throw new InvalidOperationException("Enumeration has ended.");
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException_EnumCurrent(int index)
{
throw GetInvalidOperationException_EnumCurrent(index);
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion()
{
throw new InvalidOperationException("Collection was modified during enumeration.");
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen()
{
throw new InvalidOperationException("Invalid enumerator state: enumeration cannot proceed.");
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException_InvalidOperation_NoValue()
{
throw new InvalidOperationException("No value provided.");
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException_ConcurrentOperationsNotSupported()
{
throw new InvalidOperationException("Concurrent operations are not supported.");
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException_HandleIsNotInitialized()
{
throw new InvalidOperationException("Handle is not initialized.");
}
[DoesNotReturn]
internal static void ThrowFormatException_BadFormatSpecifier()
{
throw new FormatException("Bad format specifier.");
@ -300,17 +348,17 @@ namespace Avalonia.Collections.Pooled
return new InvalidOperationException(GetResourceString(resource));
}
private static ArgumentException GetWrongKeyTypeArgumentException(object key, Type targetType)
private static ArgumentException GetWrongKeyTypeArgumentException(object? key, Type targetType)
{
return new ArgumentException($"Wrong key type. Expected {targetType}, got: '{key}'.", nameof(key));
}
private static ArgumentException GetWrongValueTypeArgumentException(object value, Type targetType)
private static ArgumentException GetWrongValueTypeArgumentException(object? value, Type targetType)
{
return new ArgumentException($"Wrong value type. Expected {targetType}, got: '{value}'.", nameof(value));
}
private static KeyNotFoundException GetKeyNotFoundException(object key)
private static KeyNotFoundException GetKeyNotFoundException(object? key)
{
return new KeyNotFoundException($"Key not found: {key}");
}
@ -342,7 +390,7 @@ namespace Avalonia.Collections.Pooled
// Aggressively inline so the jit evaluates the if in place and either drops the call altogether
// Or just leaves null test and call to the Non-returning ThrowHelper.ThrowArgumentNullException
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void IfNullAndNullsAreIllegalThenThrow<T>(object value, ExceptionArgument argName)
internal static void IfNullAndNullsAreIllegalThenThrow<T>(object? value, ExceptionArgument argName)
{
// Note that default(T) is not equal to null for value types except when T is Nullable<U>.
if (!(default(T) == null) && value == null)

3
src/Avalonia.Styling/Controls/ResourceDictionary.cs

@ -68,7 +68,8 @@ namespace Avalonia.Controls
{
x.RemoveOwner(Owner);
}
}, null);
},
() => throw new NotSupportedException("Dictionary reset not supported"));
}
return _mergedDictionaries;

Loading…
Cancel
Save