visual que puede programacion nombres nombre namespace métodos miembros indicadores espacios espacio error distribuidos directamente contener como codigos campos basicos c# vb.net reflection assemblies namespaces

que - indicadores c#



Búsqueda de todos los espacios de nombres en un ensamblaje utilizando Reflection(DotNET) (6)

Aquí hay una especie de forma lineal, todavía en esencia está iterando sobre cada elemento pero el código es mucho más limpio.

var nameSpaces = from type in Assembly.GetExecutingAssembly().GetTypes() select type.Namespace; nameSpaces = nameSpaces.Distinct();

Además, si su código de generación automática es mejor para calificarlo todo, entonces no tendrá que preocuparse por los conflictos de nombres en el código generado.

Tengo un ensamblaje (cargado como ReflectionOnly) y quiero encontrar todos los espacios de nombres en este ensamblaje para poder convertirlos en declaraciones "utilizando" ("Importaciones" en VB) para una plantilla de archivo de código fuente generada automáticamente.

Idealmente, me gustaría limitarme solo a los espacios de nombres de nivel superior, así que en lugar de:

using System; using System.Collections; using System.Collections.Generic;

solo obtendrías

using System;

Noté que hay una propiedad de espacio de nombres en la clase System.Type, pero ¿hay una mejor manera de recopilar espacios de nombres dentro de un conjunto que no implique iterar sobre todos los tipos y eliminar cadenas de espacios de nombres duplicadas?

Muy agradecido, david


Los espacios de nombres son en realidad solo una convención de nomenclatura en los nombres de tipo, por lo que solo "existen" como un patrón que se repite en muchos nombres de tipo calificados. Así que tienes que recorrer todos los tipos. Sin embargo, el código para esto probablemente se puede escribir como una sola expresión de Linq.


No tendrá más remedio que iterar sobre todas las clases.

Tenga en cuenta que las importaciones no funcionan recursivamente. "using System" no importará ninguna clase de subnamespaces como System.Collections o System.Collections.Generic, en su lugar, debe incluirlos todos.


No, no hay un atajo para esto, aunque LINQ lo hace relativamente fácil. Por ejemplo, en C # el "conjunto de espacios de nombres" en bruto sería:

var namespaces = assembly.GetTypes() .Select(t => t.Namespace) .Distinct();

Para obtener el espacio de nombres de nivel superior, probablemente debería escribir un método:

var topLevel = assembly.GetTypes() .Select(t => GetTopLevelNamespace(t)) .Distinct(); ... static string GetTopLevelNamespace(Type t) { string ns = t.Namespace ?? ""; int firstDot = ns.IndexOf(''.''); return firstDot == -1 ? ns : ns.Substring(0, firstDot); }

Estoy intrigado en cuanto a por qué solo necesitas espacios de nombres de nivel superior, aunque ... parece una restricción extraña.


Un poco de LINQ?

var qry = (from type in assembly.GetTypes() where !string.IsNullOrEmpty(type.Namespace) let dotIndex = type.Namespace.IndexOf(''.'') let topLevel = dotIndex < 0 ? type.Namespace : type.Namespace.Substring(0, dotIndex) orderby topLevel select topLevel).Distinct(); foreach (var ns in qry) { Console.WriteLine(ns); }


public static void Main() { var assembly = ...; Console.Write(CreateUsings(FilterToTopLevel(GetNamespaces(assembly)))); } private static string CreateUsings(IEnumerable<string> namespaces) { return namespaces.Aggregate(String.Empty, (u, n) => u + "using " + n + ";" + Environment.NewLine); } private static IEnumerable<string> FilterToTopLevel(IEnumerable<string> namespaces) { return namespaces.Select(n => n.Split(''.'').First()).Distinct(); } private static IEnumerable<string> GetNamespaces(Assembly assembly) { return (assembly.GetTypes().Select(t => t.Namespace) .Where(n => !String.IsNullOrEmpty(n)) .Distinct()); }