Решение
public enum ArrayKind
{
/// <summary>
/// Not an array.
/// </summary>
None,
/// <summary>
/// A vector array. Can only have a single dimension.
/// </summary>
Vector,
/// <summary>
/// A multidimensional array. Can have 1 to 32 dimensions.
/// </summary>
MultiDimensional,
}
public static class TypeExtensions
{
/// <summary>
/// Determines the kind of array that the specified type is.
/// </summary>
/// <param name="type">The type.</param>
/// <returns>
/// The kind of array of the specified type.
/// </returns>
/// <exception cref="ArgumentNullException"><paramref name="type"/> is null.</exception>
public static ArrayKind GetArrayKind(
this Type type)
{
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}
ArrayKind result;
if (!type.IsArray)
{
result = ArrayKind.None;
}
else if (type.GetArrayRank() > 1)
{
result = ArrayKind.MultiDimensional;
}
else if (type == type.GetElementType().MakeArrayType())
{
result = ArrayKind.Vector;
}
else
{
result = ArrayKind.MultiDimensional;
}
return result;
}
}
Тесты
Требуется xUnit и FluentAssertions
[Fact]
public static void GetArrayKind___Should_throw_ArgumentNullException___When_parameter_type_is_null()
{
// Arrange, Act
var actual = Record.Exception(() => TypeExtensions.GetArrayKind(null));
// Assert
actual.Should().BeOfType<ArgumentNullException>();
actual.Message.Should().Contain("type");
}
[Fact]
public static void GetArrayKind___Should_return_ArrayKind_None___When_type_is_not_an_array()
{
// Arrange
var types = new[]
{
typeof(object),
typeof(string),
typeof(Guid),
typeof(DateTime),
typeof(int),
typeof(Guid?),
typeof(DateTime?),
typeof(int?),
typeof(IReadOnlyCollection<object>),
typeof(IReadOnlyCollection<string>),
typeof(IReadOnlyCollection<Guid>),
typeof(IReadOnlyCollection<DateTime>),
typeof(IReadOnlyCollection<int>),
typeof(List<object>),
typeof(List<string>),
typeof(List<Guid>),
typeof(List<DateTime>),
typeof(List<int>),
};
// Act
var actuals = types.Select(_ => _.GetArrayKind()).ToList();
// Assert
actuals.Should().AllBeEquivalentTo(ArrayKind.None);
}
[Fact]
public static void GetArrayKind___Should_return_ArrayKind_Vector___When_type_is_a_vector_array()
{
// Arrange
var types = new[]
{
typeof(object[]),
typeof(string[]),
typeof(Guid[]),
typeof(DateTime[]),
typeof(int[]),
typeof(Guid?[]),
typeof(DateTime?[]),
typeof(int?[]),
typeof(IReadOnlyCollection<object>[]),
typeof(IReadOnlyCollection<string>[]),
typeof(IReadOnlyCollection<Guid>[]),
typeof(IReadOnlyCollection<DateTime>[]),
typeof(IReadOnlyCollection<int>[]),
typeof(List<object>[]),
typeof(List<string>[]),
typeof(List<Guid>[]),
typeof(List<DateTime>[]),
typeof(List<int>[]),
typeof(object[][]),
typeof(string[][]),
typeof(Guid[][]),
typeof(DateTime[][]),
typeof(int[][]),
typeof(Guid?[][]),
typeof(DateTime?[][]),
typeof(int?[][]),
typeof(IReadOnlyCollection<object>[][]),
typeof(IReadOnlyCollection<string>[][]),
typeof(IReadOnlyCollection<Guid>[][]),
typeof(IReadOnlyCollection<DateTime>[][]),
typeof(IReadOnlyCollection<int>[][]),
typeof(List<object>[][]),
typeof(List<string>[][]),
typeof(List<Guid>[][]),
typeof(List<DateTime>[][]),
typeof(List<int>[][]),
typeof(object[][,]),
typeof(string[][,]),
typeof(Guid[][,]),
typeof(DateTime[][,]),
typeof(int[][,]),
typeof(Guid?[][,]),
typeof(DateTime?[][,]),
typeof(int?[][,]),
typeof(IReadOnlyCollection<object>[][,]),
typeof(IReadOnlyCollection<string>[][,]),
typeof(IReadOnlyCollection<Guid>[][,]),
typeof(IReadOnlyCollection<DateTime>[][,]),
typeof(IReadOnlyCollection<int>[][,]),
typeof(List<object>[][,]),
typeof(List<string>[][,]),
typeof(List<Guid>[][,]),
typeof(List<DateTime>[][,]),
typeof(List<int>[][,]),
};
// Act
var actuals = types.Select(_ => _.GetArrayKind()).ToList();
// Assert
actuals.Should().AllBeEquivalentTo(ArrayKind.Vector);
}
[Fact]
public static void GetArrayKind___Should_return_ArrayKind_MultiDimensional___When_type_is_a_multidimensional_array()
{
// Arrange
var types = new[]
{
typeof(object[,]),
typeof(string[,]),
typeof(Guid[,]),
typeof(DateTime[,]),
typeof(int[,]),
typeof(Guid?[,]),
typeof(DateTime?[,]),
typeof(int?[,]),
typeof(IReadOnlyCollection<object>[,]),
typeof(IReadOnlyCollection<string>[,]),
typeof(IReadOnlyCollection<Guid>[,]),
typeof(IReadOnlyCollection<DateTime>[,]),
typeof(IReadOnlyCollection<int>[,]),
typeof(List<object>[,]),
typeof(List<string>[,]),
typeof(List<Guid>[,]),
typeof(List<DateTime>[,]),
typeof(List<int>[,]),
typeof(object[,][]),
typeof(string[,][]),
typeof(Guid[,][]),
typeof(DateTime[,][]),
typeof(int[,][]),
typeof(Guid?[,][]),
typeof(DateTime?[,][]),
typeof(int?[,][]),
typeof(IReadOnlyCollection<object>[,][]),
typeof(IReadOnlyCollection<string>[,][]),
typeof(IReadOnlyCollection<Guid>[,][]),
typeof(IReadOnlyCollection<DateTime>[,][]),
typeof(IReadOnlyCollection<int>[,][]),
typeof(List<object>[,][]),
typeof(List<string>[,][]),
typeof(List<Guid>[,][]),
typeof(List<DateTime>[,][]),
typeof(List<int>[,][]),
typeof(object).MakeArrayType(1),
typeof(string).MakeArrayType(1),
typeof(Guid).MakeArrayType(1),
typeof(DateTime).MakeArrayType(1),
typeof(int).MakeArrayType(1),
typeof(Guid?).MakeArrayType(1),
typeof(DateTime?).MakeArrayType(1),
typeof(int?).MakeArrayType(1),
typeof(IReadOnlyCollection<object>).MakeArrayType(1),
typeof(IReadOnlyCollection<string>).MakeArrayType(1),
typeof(IReadOnlyCollection<Guid>).MakeArrayType(1),
typeof(IReadOnlyCollection<DateTime>).MakeArrayType(1),
typeof(IReadOnlyCollection<int>).MakeArrayType(1),
typeof(List<object>).MakeArrayType(1),
typeof(List<string>).MakeArrayType(1),
typeof(List<Guid>).MakeArrayType(1),
typeof(List<DateTime>).MakeArrayType(1),
typeof(List<int>).MakeArrayType(1),
typeof(object[]).MakeArrayType(1),
typeof(string[]).MakeArrayType(1),
typeof(Guid[]).MakeArrayType(1),
typeof(DateTime[]).MakeArrayType(1),
typeof(int[]).MakeArrayType(1),
typeof(Guid?[]).MakeArrayType(1),
typeof(DateTime?[]).MakeArrayType(1),
typeof(int?[]).MakeArrayType(1),
typeof(IReadOnlyCollection<object>[]).MakeArrayType(1),
typeof(IReadOnlyCollection<string>[]).MakeArrayType(1),
typeof(IReadOnlyCollection<Guid>[]).MakeArrayType(1),
typeof(IReadOnlyCollection<DateTime>[]).MakeArrayType(1),
typeof(IReadOnlyCollection<int>[]).MakeArrayType(1),
typeof(List<object>[]).MakeArrayType(1),
typeof(List<string>[]).MakeArrayType(1),
typeof(List<Guid>[]).MakeArrayType(1),
typeof(List<DateTime>[]).MakeArrayType(1),
typeof(List<int>[]).MakeArrayType(1),
};
// Act
var actuals = types.Select(_ => _.GetArrayKind()).ToList();
// Assert
actuals.Should().AllBeEquivalentTo(ArrayKind.MultiDimensional);
}