c# - 获取与类型关联的所有命名空间?
问题描述
有没有办法使用反射获取与类/类型关联的所有命名空间?
例如,假设我的变量是:
var list = List<MyClass>
我的班级被定义为
public class MyClass
{
property int32 MyNumber {get; set;}
}
我希望能够返回以下命名空间:
- MyCompany.MyClass(因为它被我的 MyClass 使用)
- System.Collections.Generic(因为它被 List 使用)
- 系统为 int32(因为它被 MyNumber 使用)
谢谢。
解决方案
您可以使用反射解析类型。
由于框架设计,您将获得比预期更多的结果。
我希望我没有犯太多错误。
考试
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;}
}
}
反射助手类
using System;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
namespace ConsoleApp
{
static public class ReflexionHelper
{
// See below
}
}
工具方法
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);
}
解析类型的方法
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;
}
获取一个类型的所有成员的方法
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;
}
未来的改进
分析属性和其他忘记的东西。
测试输出短路
ConsoleApp
System
System.Collections
System.Collections.Generic
System.Collections.ObjectModel
System.Reflection
System.Runtime.InteropServices
System.Runtime.Serialization
测试输出满
# 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
某些类型名称重复但 Type 实例不同...
推荐阅读
- javascript - 在 Array.prototype.map 中退一步迭代
- android - 在 Kotlin 中固定 List 大小的最佳方法是什么
- java - Spring - 在@Autowired 上使用@Resource 以获得更好的性能
- javascript - 使用 onkeypress 事件验证利率
- prometheus - 数据可以存储在本地和远程存储中吗
- asp.net-mvc - 如何在编辑页面 MVC 中设置下拉列表选定值
- php - Mod重写删除查询(GET)详细信息
- list - 我想出了在列表中测试相等 a 和 b 的代码,但无法理解底层递归
- python - 递归序列python
- ruby-on-rails - 使用 rspec(ruby 项目)编写文件验证规范