c# .net multidimensional-array typeof gettype

c# - Valor inesperado de System.Type.FullName



.net multidimensional-array (2)

Hace poco necesité crear un nombre específico de C # (que siempre debe incluir global :: specifier) ​​para un tipo arbitrario y he encontrado el siguiente problema:

// 1 - value: System.String[,,,][,,][,] string unexpectedFullName = typeof( string[,][,,][,,,] ).FullName; // 2 - value: System.String[,][,,][,,,] string expectedFullName = Type.GetType( "System.String[,][,,][,,,]" ).FullName;

Esperaba que el valor devuelto fuera igual en ambos casos. Sin embargo, por alguna razón, la parte del valor relacionada con la matriz parece invertirse (caso 1). ¿Es esta reversa el comportamiento esperado?


Nota: Esto no responde directamente a su pregunta.

¿Es esta reversa el comportamiento esperado?

pero siento que se suma a ello.

Puede usar GenerateCodeFromExpression para devolver una cadena que podría usarse para generar el código para generar el tipo para usted, por ejemplo, usando este código (modificado de esta respuesta SO por hvd ):

/// <summary> /// <para>Returns a readable name for this type.</para> /// <para>e.g. for type = typeof(IEnumerable&lt;IComparable&lt;int&gt;&gt;),</para> /// <para>type.FriendlyName() returns System.Collections.Generic.IEnumerable&lt;System.IComparable&lt;int&gt;&gt;</para> /// <para>type.Name returns IEnumerable`1</para> /// <para>type.FullName() returns System.Collections.Generic.IEnumerable`1[[System.IComparable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]</para> /// </summary> public static string FriendlyName(this Type type) { string result; using ( var codeDomProvider = CodeDomProvider.CreateProvider("C#") ) { var typeReferenceExpression = new CodeTypeReferenceExpression(new CodeTypeReference(type)); using ( var writer = new StringWriter() ) { codeDomProvider.GenerateCodeFromExpression(typeReferenceExpression, writer, new CodeGeneratorOptions()); result = writer.GetStringBuilder().ToString(); } } return result; }

Al permitir que codeDomProvider maneje la representación de la cadena, puede estar seguro de que lo que se genere coincidirá con la forma en que definiría el Tipo.

Resultados con FullName :

// returns "System.String[,,,][,,][,]" typeof(string[,][, ,][, , ,]).FullName; // returns "System.String[,][,,][,,,]" typeof(string[, , ,][, ,][,]).FullName; // returns "System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]" typeof(List<int>).FullName;

Resultados con FriendlyName

// returns "string[,][,,][,,,]" typeof(string[,][, ,][, , ,]).FriendlyName(); // returns "string[,,,][,,][,]" typeof(string[, , ,][, ,][,]).FriendlyName(); // returns "System.Collections.Generic.List<int>" typeof(List<int>).FriendlyName();


Si bien el valor devuelto por Type.FullName y el identificador de tipo C # a veces son los mismos, esto no está garantizado. Tenga en cuenta que Type.FullName devuelve el mismo valor independientemente del idioma de CLI desde el que se llame, ya sea C #, VB.NET, Oxygene o cualquier otra cosa.

Para matrices multidimensionales e irregulares, la sintaxis de C # enumera los índices en el orden en que se escriben más adelante, mientras que la sintaxis de reflexión devuelve algo que coincide con la estructura lógica de la matriz. Y una string[,][,,][,,,] (C #) string[,][,,][,,,] es, después de todo, un valor de tipo string , una matriz de 4 dimensiones (es decir, string[,,,] ), una string[,,,] tridimensional matriz (es decir, string[,,,][,,] ) y de la misma una matriz bidimensional (es decir, string[,,,][,,][,] ).

En lugar de confiar en el nombre de sintaxis de reflexión devuelto por FullName , es posible que desee examinar las propiedades de la clase Type al analizar los tipos. La información como el número de dimensiones o los argumentos genéricos se puede recuperar desde allí.

Al construir tipos, también puede usar métodos como MakeArrayType o MakeGenericType para crear tipos complejos en tiempo de ejecución sin construir una cadena que contenga los ingredientes para los nuevos tipos.

Parte del contenido de esta respuesta fue señalado por Marc Gravell - ¡gracias!