Skip to content

Commit a8c6fed

Browse files
committed
Refactor symbol cache to use descriptors, add indented APIs
Major refactor: symbol data now constructed from descriptors, not cache keys. SymbolReflectionInfoCacheKeyInternal moved and expanded; cache key management improved with reverse mapping. TypeData and MethodData updated for new member handling. Introduced ParameterListView and IParameterListView for robust parameter list access. PooledStringBuilder gains indented append/join APIs. ArgumentExceptionAdvanced extended for type assignability checks. Various bug fixes and improvements for clarity, safety, and maintainability.
1 parent d945087 commit a8c6fed

21 files changed

+1310
-468
lines changed

src/BionicCode.Utilities.Net.Common/Exception/ArgumentExceptionHelpers.cs

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ public static void ThrowIfEnumNotEqualsAny<TEnum>(IConvertible value, ReadOnlySp
400400

401401
if (message is null)
402402
{
403-
List<TEnum> disallowedValues = Enum.GetValues<TEnum>()
403+
var disallowedValues = Enum.GetValues<TEnum>()
404404
.Except(allowedValues.ToArray())
405405
.ToList();
406406

@@ -441,7 +441,7 @@ public static void ThrowIfEnumEqualsAny<TEnum>(IConvertible value, ReadOnlySpan<
441441
{
442442
if (message is null)
443443
{
444-
List<TEnum> allowedValues = Enum.GetValues<TEnum>()
444+
var allowedValues = Enum.GetValues<TEnum>()
445445
.Except(disallowedValues.ToArray())
446446
.ToList();
447447

@@ -547,6 +547,73 @@ public static void ThrowIfNotAssignableTo([NotNull] Type value, [NotNull] Type t
547547
}
548548
}
549549

550+
/// <summary>
551+
/// Throws an exception if the specified type is not assignable to the target type.
552+
/// </summary>
553+
/// <param name="value">The type to validate for assignability. Cannot be null.</param>
554+
/// <param name="target">The target type to check assignability against. Cannot be null.</param>
555+
/// <param name="paramName">The name of the parameter representing the type to validate. This value is typically provided automatically
556+
/// and should not be set explicitly in most cases.</param>
557+
/// <param name="message">An optional exception message.</param>
558+
/// <exception cref="ArgumentException">Thrown if <paramref name="value"/> is not assignable to <paramref name="target"/>.</exception>
559+
public static void ThrowIfNotAssignableTo<TValue, TTarget>([NotNull] TValue value, [NotNull] TTarget target, [CallerArgumentExpression(nameof(value))] string? paramName = null, string? message = null)
560+
{
561+
ArgumentNullException.ThrowIfNull(value, paramName);
562+
ArgumentNullException.ThrowIfNull(target);
563+
564+
Type targetType = target.GetType();
565+
Type valueType = value.GetType();
566+
if (!valueType.IsAssignableTo(targetType))
567+
{
568+
throw new ArgumentException(
569+
message ?? $"The provided type is not assignable to the expected type. Allowed: '{targetType.FullName}', Found: '{valueType.FullName}'.",
570+
paramName);
571+
}
572+
}
573+
574+
/// <summary>
575+
/// Throws an exception if the specified type is not assignable to the target type.
576+
/// </summary>
577+
/// <typeparam name="TValue">The type to validate for assignability. Cannot be null.</param>
578+
/// <typeparam name="TTarget">The target type to check assignability against. Cannot be null.</param>
579+
/// <param name="paramName">The name of the parameter representing the type to validate. This value is typically provided automatically
580+
/// and should not be set explicitly in most cases.</param>
581+
/// <param name="message">An optional exception message.</param>
582+
/// <exception cref="ArgumentException">Thrown if <paramref name="value"/> is not assignable to <paramref name="target"/>.</exception>
583+
public static void ThrowIfNotAssignableTo<TValue, TTarget>(string? message = null)
584+
{
585+
Type targetType = typeof(TTarget);
586+
Type valueType = typeof(TValue);
587+
if (!valueType.IsAssignableTo(targetType))
588+
{
589+
throw new ArgumentException(
590+
message ?? $"The provided type is not assignable to the expected type. Allowed: '{targetType.FullName}', Found: '{valueType.FullName}'.",
591+
string.Empty);
592+
}
593+
}
594+
595+
/// <summary>
596+
/// Throws an exception if the specified type is not assignable to the target type.
597+
/// </summary>
598+
/// <param name="value">The type to validate for assignability. Cannot be null.</param>
599+
/// <param name="paramName">The name of the parameter representing the type to validate. This value is typically provided automatically
600+
/// and should not be set explicitly in most cases.</param>
601+
/// <typeparam name="TTarget"> The target type to check assignability against. Cannot be null.</typeparam>
602+
/// <param name="message">An optional exception message.</param>
603+
/// <exception cref="ArgumentException">Thrown if <paramref name="value"/> is not assignable to <paramref name="target"/>.</exception>
604+
public static void ThrowIfNotAssignableTo<TTarget>([NotNull] object value, [CallerArgumentExpression(nameof(value))] string? paramName = null, string? message = null)
605+
{
606+
ArgumentNullException.ThrowIfNull(value, paramName);
607+
Type targetType = typeof(TTarget);
608+
Type valueType = value.GetType();
609+
if (!valueType.IsAssignableTo(targetType))
610+
{
611+
throw new ArgumentException(
612+
message ?? $"The provided type is not assignable to the expected type. Allowed: '{targetType.FullName}', Found: '{valueType.FullName}'.",
613+
paramName);
614+
}
615+
}
616+
550617
/// <summary>
551618
/// Throws an ArgumentException if the specified condition is false.
552619
/// </summary>

0 commit comments

Comments
 (0)