tipos sharp que primitivos nativos historia datos caracteristicas alcance c# reflection

sharp - ¿Cómo puedo obtener el nombre primitivo de un tipo en C#?



tipos de datos primitivos en c sharp (6)

EDIT: estaba medio equivocado en la respuesta a continuación.

Echa un vistazo a CSharpCodeProvider.GetTypeOutput . Código de muestra:

using Microsoft.CSharp; using System; using System.CodeDom; class Test { static void Main() { var compiler = new CSharpCodeProvider(); // Just to prove a point... var type = new CodeTypeReference(typeof(Int32)); Console.WriteLine(compiler.GetTypeOutput(type)); // Prints int } }

Sin embargo, esto no traduce Nullable<T> en T? - y no puedo encontrar ninguna opción que lo haga hacerlo, aunque eso no significa que esa opción no exista :)

No hay nada en el marco para admitir esto, después de todo, son nombres específicos de C #.

(Tenga en cuenta que la string no es un tipo primitivo , por cierto).

Tendrá que hacerlo localizando Nullable`1 usted mismo, y tendrá un mapa del nombre completo del marco para cada alias.

Estoy utilizando la reflexión para imprimir una firma de método, por ejemplo,

foreach (var pi in mi.GetParameters()) { Console.WriteLine(pi.Name + ": " + pi.ParameterType.ToString()); }

Esto funciona bastante bien, pero imprime el tipo de primitivas como "System.String" en lugar de "string" y "System.Nullable`1 [System.Int32]" en lugar de "int?". ¿Hay alguna manera de obtener el nombre del parámetro tal como aparece en el código, por ejemplo,

public Example(string p1, int? p2)

huellas dactilares

p1: string p2: int?

en lugar de

p1: System.String p2: System.Nullable`1[System.Int32]


Esta question tiene dos respuestas interesantes. El aceptado de Jon Skeet prácticamente dice lo que ya dijo.

EDITAR Jon actualizó su respuesta, así que es casi lo mismo que la mía ahora. (Pero por supuesto 20 segundos antes)

Pero Luke H también da esta respuesta, que pensé que era un uso bastante impresionante del CodeDOM.

Type t = column.DataType; // Int64 StringBuilder sb = new StringBuilder(); using (StringWriter sw = new StringWriter(sb)) { var expr = new CodeTypeReferenceExpression(t); var prov = new CSharpCodeProvider(); prov.GenerateCodeFromExpression(expr, sw, new CodeGeneratorOptions()); } Console.WriteLine(sb.ToString()); // long


Esto es lo que se me ocurrió después de ~ 5 minutos de piratería. Por ejemplo:

CSharpAmbiance.GetTypeName(typeof(IDictionary<string,int?>))

devolverá System.Collections.Generic.IDictionary<string, int?> .

public static class CSharpAmbiance { private static Dictionary<Type, string> aliases = new Dictionary<Type, string>(); static CSharpAmbiance() { aliases[typeof(byte)] = "byte"; aliases[typeof(sbyte)] = "sbyte"; aliases[typeof(short)] = "short"; aliases[typeof(ushort)] = "ushort"; aliases[typeof(int)] = "int"; aliases[typeof(uint)] = "uint"; aliases[typeof(long)] = "long"; aliases[typeof(ulong)] = "ulong"; aliases[typeof(char)] = "char"; aliases[typeof(float)] = "float"; aliases[typeof(double)] = "double"; aliases[typeof(decimal)] = "decimal"; aliases[typeof(bool)] = "bool"; aliases[typeof(object)] = "object"; aliases[typeof(string)] = "string"; } private static string RemoveGenericNamePart(string name) { int backtick = name.IndexOf(''`''); if (backtick != -1) name = name.Substring(0, backtick); return name; } public static string GetTypeName(Type type) { if (type == null) throw new ArgumentNullException("type"); string keyword; if (aliases.TryGetValue(type, out keyword)) return keyword; if (type.IsArray) { var sb = new StringBuilder(); var ranks = new Queue<int>(); do { ranks.Enqueue(type.GetArrayRank() - 1); type = type.GetElementType(); } while (type.IsArray); sb.Append(GetTypeName(type)); while (ranks.Count != 0) { sb.Append(''[''); int rank = ranks.Dequeue(); for (int i = 0; i < rank; i++) sb.Append('',''); sb.Append('']''); } return sb.ToString(); } if (type.IsGenericTypeDefinition) { var sb = new StringBuilder(); sb.Append(RemoveGenericNamePart(type.FullName)); sb.Append(''<''); var args = type.GetGenericArguments().Length - 1; for (int i = 0; i < args; i++) sb.Append('',''); sb.Append(''>''); return sb.ToString(); } if (type.IsGenericType) { if (type.GetGenericTypeDefinition() == typeof(Nullable<>)) return GetTypeName(type.GetGenericArguments()[0]) + "?"; var sb = new StringBuilder(); sb.Append(RemoveGenericNamePart(type.FullName)); sb.Append(''<''); var args = type.GetGenericArguments(); for (int i = 0; i < args.Length; i++) { if (i != 0) sb.Append(", "); sb.Append(GetTypeName(args[i])); } sb.Append(''>''); return sb.ToString(); } return type.FullName; } }


No es el código más hermoso del mundo, pero esto es lo que terminé haciendo: (basándose en el código de Cornard)

public static string CSharpName(this Type type) { if (!type.FullName.StartsWith("System")) return type.Name; var compiler = new CSharpCodeProvider(); var t = new CodeTypeReference(type); var output = compiler.GetTypeOutput(t); output = output.Replace("System.",""); if (output.Contains("Nullable<")) output = output.Replace("Nullable","").Replace(">","").Replace("<","") + "?"; return output; }


No. string es solo una representación de System.String - string realmente no significa nada detrás de la escena.

Por cierto, para pasar a System.Nullable''1[System.Int32] , puedes usar Nullable.GetUnderlyingType(type);


Otra opción, basada en las otras respuestas aquí.

caracteristicas:

  • Convertir String a string e Int32 a int etc.
  • ¿Tratar con Nullable<Int32> como int? etc
  • Suprimir System.DateTime para ser DateTime
  • Todos los demás tipos están escritos en su totalidad.

Se trata de los casos simples que necesitaba, no estoy seguro de si manejará bien los tipos complejos.

Type type = /* Get a type reference somehow */ var compiler = new CSharpCodeProvider(); if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) { return compiler.GetTypeOutput(new CodeTypeReference(type.GetGenericArguments()[0])).Replace("System.","") + "?"; } else { return compiler.GetTypeOutput(new CodeTypeReference(type)).Replace("System.",""); }