Getting All Types in a Namespace Via Reflection

Get all namespaces associated with a Type?

You can parse the type using reflecion.

You will get many more results than expected because of the framework design.

I hope I haven't made too many mistakes.

The test

namespace ConsoleApp
{
public class Program
{
static public void Main(string[] args)
{
var list = new List<MyClass>();
var typeSearched = list.GetType();
Console.WriteLine($"{typeSearched.Name} needs these namespaces:");
foreach ( var item in typeSearched.GetUsingNamespaces().OrderBy(kvp => kvp.Key) )
{
string names = string.Join(Environment.NewLine + " ",
item.Value.Select(t => t.Name)
.OrderBy(n => n));
Console.WriteLine($"# {item.Key} for type(s):" + Environment.NewLine +
$" {names}");
Console.WriteLine();
}
}
public class MyClass
{
public Int32 MyNumber {get; set;}
}
}

The reflexion helper class

using System;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;

namespace ConsoleApp
{
static public class ReflexionHelper
{
// See below
}
}

Tools methods

static public void AddNoDuplicates<T>(this IList<T> list, T value)
{
if ( !list.Contains(value) ) list.Add(value);
}

static public void AddNoDuplicates<TKey, TValue>(this IDictionary<TKey, List<TValue>> list,
TKey key, TValue value)
{
if ( key == null ) return;
if ( !list.ContainsKey(key) )
list.Add(key, new List<TValue>() { value });
else
if ( !list[key].Contains(value) )
list[key].Add(value);
}

static public void AddRangeNoDuplicates<T>(this IList<T> list, IEnumerable<T> collection)
{
foreach ( T value in collection )
if ( !list.Contains(value) )
list.Add(value);
}

The method to parse the type

static public Dictionary<string, List<Type>> GetUsingNamespaces(this Type typeSearched)
{
var result = new Dictionary<string, List<Type>>();
result.AddNoDuplicates(typeSearched.Namespace, typeSearched);
foreach ( Type type in typeSearched.GetMembersTypes() )
{
result.AddNoDuplicates(type.Namespace, type);
foreach ( var implement in type.GetInterfaces() )
result.AddNoDuplicates(implement.Namespace, implement);
foreach ( var argument in type.GetGenericArguments() )
result.AddNoDuplicates(argument.Namespace, argument);
}
return result;
}

The method to get all members of a type

static public List<Type> GetMembersTypes(this Type type)
{
var flags = BindingFlags.Static
| BindingFlags.Instance
| BindingFlags.Public
| BindingFlags.NonPublic;
var result = new List<Type>();
foreach ( var field in type.GetFields(flags) )
result.AddNoDuplicates(field.FieldType);
foreach ( var property in type.GetProperties(flags) )
result.AddNoDuplicates(property.PropertyType);
foreach ( var ev in type.GetEvents(flags) )
result.AddNoDuplicates(ev.EventHandlerType);
foreach ( var method in type.GetMethods(flags) )
{
result.AddNoDuplicates(method.ReturnType);
foreach ( var a in method.GetParameters() )
result.AddNoDuplicates(a.ParameterType);
}
foreach ( var constructor in type.GetConstructors() )
foreach ( var param in constructor.GetParameters() )
result.AddNoDuplicates(param.ParameterType);
foreach ( var nested in type.GetNestedTypes(flags) )
result.AddRangeNoDuplicates(GetMembersTypes(nested));
return result;
}

Future improvements

Analyze attributes and other things forgotten.

Test output short

ConsoleApp
System
System.Collections
System.Collections.Generic
System.Collections.ObjectModel
System.Reflection
System.Runtime.InteropServices
System.Runtime.Serialization

Test output full

# ConsoleApp for type(s):
MyClass
MyClass[]

# System for type(s):
Action`1
Array
Boolean
Comparison`1
Converter`2
ICloneable
IComparable
IComparable`1
IComparable`1
IComparable`1
IConvertible
IDisposable
IEquatable`1
IEquatable`1
IEquatable`1
IFormattable
Int32
Object
Predicate`1
String
Type
Void

# System.Collections for type(s):
ICollection
IEnumerable
IEnumerator
IList
IStructuralComparable
IStructuralEquatable

# System.Collections.Generic for type(s):
Enumerator
ICollection`1
ICollection`1
ICollection`1
ICollection`1
IComparer`1
IEnumerable`1
IEnumerable`1
IEnumerable`1
IEnumerable`1
IEnumerable`1
IEnumerator`1
IEnumerator`1
IList`1
IList`1
IList`1
IList`1
IReadOnlyCollection`1
IReadOnlyCollection`1
IReadOnlyCollection`1
IReadOnlyCollection`1
IReadOnlyList`1
IReadOnlyList`1
IReadOnlyList`1
IReadOnlyList`1
List`1
List`1
List`1
List`1
T
T
T[]
TOutput

# System.Collections.ObjectModel for type(s):
ReadOnlyCollection`1

# System.Reflection for type(s):
ICustomAttributeProvider
IReflect

# System.Runtime.InteropServices for type(s):
_MemberInfo
_Type

# System.Runtime.Serialization for type(s):
ISerializable

Some type names are duplicated but the Type instance is different...

Create a list of all classes in namespace using reflection and cast to their real type

SOLVED: The issue was I had internal constructors and the System.Activator couldn't create an instance of the class.

C# Get a List of Classes in a Namespace per Reflection

because adding Type to combobox makes type.ToString() and puts string representation into combobox, you can use

var instance = Activator.CreateInstance(Type.GetType(cbModule4.SelectedText))

When passing type, you can do:

var instance = Activator.CreateInstance(theList[0]))

Is there a way to get all namespaces you're 'using' within a class through C# code?

This will work for all types in methods of the declaring class, however it wont give all namespaces for all classes in the file where it was before compiling. That is impossible because after compilation the framework cannot know what was where in files.

So if you have one CLASS per file this will work:
If you are missing something (i look for fields and methods, maybe something is not taken in account, if that is so just add)

List<string> namespaces = new List<string>();

var m = MethodInfo.GetCurrentMethod();

foreach (var mb in m.DeclaringType.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic))
{
if (mb.MemberType == MemberTypes.Method && ((MethodBase)mb).GetMethodBody() != null)
{

foreach (var p in ((MethodInfo)mb).GetMethodBody().LocalVariables)
{
if (!namespaces.Contains(p.LocalType.Namespace))
{
namespaces.Add(p.LocalType.Namespace);
Console.WriteLine(p.LocalType.Namespace);
}
}
}
else if (mb.MemberType == MemberTypes.Field) {
string ns = ((System.Reflection.FieldInfo)mb).FieldType.Namespace;
if (!namespaces.Contains(ns))
{
namespaces.Add(ns);
Console.WriteLine(ns);
}
}
}

Sample output for my case:

System
System.Collections.Generic
System.Reflection
WindowsFormsApplication2
System.Linq.Expressions

How can I get all classes within a namespace?

You will need to do it "backwards"; list all the types in an assembly and then checking the namespace of each type:

using System.Reflection;
private Type[] GetTypesInNamespace(Assembly assembly, string nameSpace)
{
return
assembly.GetTypes()
.Where(t => String.Equals(t.Namespace, nameSpace, StringComparison.Ordinal))
.ToArray();
}

Example of usage:

Type[] typelist = GetTypesInNamespace(Assembly.GetExecutingAssembly(), "MyNamespace");
for (int i = 0; i < typelist.Length; i++)
{
Console.WriteLine(typelist[i].Name);
}

For anything before .Net 2.0 where Assembly.GetExecutingAssembly() is not available, you will need a small workaround to get the assembly:

Assembly myAssembly = typeof(<Namespace>.<someClass>).GetTypeInfo().Assembly;
Type[] typelist = GetTypesInNamespace(myAssembly, "<Namespace>");
for (int i = 0; i < typelist.Length; i++)
{
Console.WriteLine(typelist[i].Name);
}

Get list of classes in namespace in C#


var theList = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.Namespace == "your.name.space")
.ToList();


Related Topics



Leave a reply



Submit