Andras Zoltan Andras Zoltan -3 years ago 93
C# Question

Array types with same element type & rank not equal

Very simple:

var equal1 = typeof(object[]) == typeof(object).MakeArrayType();
var equal2 = typeof(object[]) == typeof(object).MakeArrayType(1);
var equal3 = typeof(object[,]) == typeof(object).MakeArrayType(2);


The assumption is that all three should be true, but it turns out that
equal2
is
false
- which doesn't really make sense given that the first two
MakeArrayType
calls are equivalent and the resulting array types are the same.


The only difference I can actually discern is that explicitly passing the rank of the array type as '1' yields a
Type
whose
Name
is
"Object[*]"
whereas omitting it yields
"Object[]"
.


So I thought, perhaps the rank of
object[]
isn't
1
(even though it clearly is!) - so I did this:

var type1 = typeof(object[]);
var type2 = type1.GetElementType().MakeArrayType(type1.GetArrayRank());
var equal = type1 == type2; //false


The types now definitely have the same rank, but are not equal.


This scenario is more like my current scenario as I try to build Array covariance into Rezolver - so I'm recomposing array types by walking base hierarchies and using
MakeArrayType
with the original array type's rank.


So - can anyone explain why two array types with identical rank are not considered equal?

I realise there's likely some nuance I'm missing here, and that there are workarounds I can use, I'm just curious as to what's going on!

Answer Source

The documentation explains the difference:

The common language runtime makes a distinction between vectors (that is, one-dimensional arrays that are always zero-based) and multidimensional arrays. A vector, which always has only one dimension, is not the same as a multidimensional array that happens to have only one dimension. You cannot use this method overload to create a vector type; if rank is 1, this method overload returns a multidimensional array type that happens to have one dimension. Use the MakeArrayType() method overload to create vector types.

So basically, equal1 returns a vector, and equal2 returns a multidimensional array that happens to have a rank of 1.

The two types are treated very differently in the CLR.

Interestingly, if you create an instance of the type, you end up with a vector again:

var type = typeof(object).MakeArrayType(1);
// Create an instance with length 2
var array = Activator.CreateInstance(type, 2);
Console.WriteLine(array.GetType());            // System.Object[]
Console.WriteLine(type);                       // System.Object[*]
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download