Skip to content

Commit ff71722

Browse files
committed
feat(反射): 添加反射扩展方法集提供统一API行为
添加 ReflectionExtensions 类,封装 Type 和 TypeInfo 在不同运行时环境下的反射操作差异, 提供统一的扩展方法集用于获取类型信息、属性、字段、方法等反射操作, 以简化跨平台开发时的反射使用并保持行为一致性。
1 parent ede3c76 commit ff71722

1 file changed

Lines changed: 268 additions & 0 deletions

File tree

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
// ==========================================================================================
2+
// GameFrameX 组织及其衍生项目的版权、商标、专利及其他相关权利
3+
// GameFrameX organization and its derivative projects' copyrights, trademarks, patents, and related rights
4+
// 均受中华人民共和国及相关国际法律法规保护。
5+
// are protected by the laws of the People's Republic of China and relevant international regulations.
6+
//
7+
// 使用本项目须严格遵守相应法律法规及开源许可证之规定。
8+
// Usage of this project must strictly comply with applicable laws, regulations, and open-source licenses.
9+
//
10+
// 本项目采用 MIT 许可证与 Apache License 2.0 双许可证分发,
11+
// This project is dual-licensed under the MIT License and Apache License 2.0,
12+
// 完整许可证文本请参见源代码根目录下的 LICENSE 文件。
13+
// please refer to the LICENSE file in the root directory of the source code for the full license text.
14+
//
15+
// 禁止利用本项目实施任何危害国家安全、破坏社会秩序、
16+
// It is prohibited to use this project to engage in any activities that endanger national security, disrupt social order,
17+
// 侵犯他人合法权益等法律法规所禁止的行为!
18+
// or infringe upon the legitimate rights and interests of others, as prohibited by laws and regulations!
19+
// 因基于本项目二次开发所产生的一切法律纠纷与责任,
20+
// Any legal disputes and liabilities arising from secondary development based on this project
21+
// 本项目组织与贡献者概不承担。
22+
// shall be borne solely by the developer; the project organization and contributors assume no responsibility.
23+
//
24+
// GitHub 仓库:https://github.com/GameFrameX
25+
// GitHub Repository: https://github.com/GameFrameX
26+
// Gitee 仓库:https://gitee.com/GameFrameX
27+
// Gitee Repository: https://gitee.com/GameFrameX
28+
// 官方文档:https://gameframex.doc.alianblank.com/
29+
// Official Documentation: https://gameframex.doc.alianblank.com/
30+
// ==========================================================================================
31+
32+
using System.Reflection;
33+
34+
namespace GameFrameX.Foundation.Extensions;
35+
36+
/// <summary>
37+
/// 反射扩展类,提供了一系列用于反射操作的扩展方法
38+
/// </summary>
39+
public static class ReflectionExtensions
40+
{
41+
/// <summary>
42+
/// 为 <see cref="System.Type"/> 与反射相关操作提供轻量扩展,统一不同运行时的 API 行为。
43+
/// </summary>
44+
/// <remarks>
45+
/// 该扩展集主要封装 <see cref="System.Reflection.TypeInfo"/> 在不同目标框架上的差异,
46+
/// 以便在 .NET Framework 与 .NET(Core/5+)之间获得一致的反射体验。
47+
/// </remarks>
48+
/// <seealso cref="System.Type"/>
49+
/// <seealso cref="System.Reflection.TypeInfo"/>
50+
/// <summary>
51+
/// 获取类型的 TypeInfo 相关行为的统一表示。对于 .NET 中 <see cref="System.Type"/> 即 <see cref="System.Reflection.TypeInfo"/> 的场景,直接返回输入类型。
52+
/// </summary>
53+
/// <param name="typeInfo">要获取元信息的类型实例。</param>
54+
/// <returns>与 <see cref="System.Reflection.TypeInfo"/> 行为兼容的类型对象(此处返回 <see cref="System.Type"/>)。</returns>
55+
/// <remarks>
56+
/// 在部分框架中 <see cref="System.Type"/> 与 <see cref="System.Reflection.TypeInfo"/> 一致;该方法提供统一调用入口。
57+
/// </remarks>
58+
/// <exception cref="System.NullReferenceException">当 <paramref name="typeInfo"/> 为 <see langword="null"/> 时。</exception>
59+
/// <seealso cref="System.Reflection.TypeInfo"/>
60+
public static Type GetTypeInfo(this Type typeInfo)
61+
{
62+
return typeInfo;
63+
}
64+
65+
/// <summary>
66+
/// 获取类型的泛型参数集合。
67+
/// </summary>
68+
/// <param name="type">要检查的类型。</param>
69+
/// <returns>包含泛型参数的 <see cref="System.Type[]"/>;非泛型类型返回空数组。</returns>
70+
/// <remarks>
71+
/// 示例:
72+
/// - 对 <see cref="System.Collections.Generic.List{T}"/>,其 {T} 将作为一个元素返回;
73+
/// - 对 <see cref="System.Nullable{T}"/>,返回对应的 {T};
74+
/// - 非泛型类型返回长度为 0 的数组。
75+
/// </remarks>
76+
/// <exception cref="System.NullReferenceException">当 <paramref name="type"/> 为 <see langword="null"/> 时。</exception>
77+
/// <seealso cref="System.Type.GetGenericArguments"/>
78+
/// <seealso cref="System.Nullable{T}"/>
79+
/// <seealso cref="System.Collections.Generic.List{T}"/>
80+
public static Type[] GetGenericArguments(this Type type)
81+
{
82+
var reval = type.GetTypeInfo().GetGenericArguments();
83+
return reval;
84+
}
85+
86+
/// <summary>
87+
/// 判断类型是否为泛型类型。
88+
/// </summary>
89+
/// <param name="type">要检查的类型。</param>
90+
/// <returns>若为泛型类型返回 <see langword="true"/>,否则返回 <see langword="false"/>。</returns>
91+
/// <remarks>
92+
/// 开放泛型与封闭泛型均视为泛型类型,例如 <see cref="System.Collections.Generic.List{T}"/> 与 <see cref="System.Collections.Generic.List{System.String}"/>。
93+
/// </remarks>
94+
/// <exception cref="System.NullReferenceException">当 <paramref name="type"/> 为 <see langword="null"/> 时。</exception>
95+
/// <seealso cref="System.Type.IsGenericType"/>
96+
public static bool IsGenericType(this Type type)
97+
{
98+
var reval = type.GetTypeInfo().IsGenericType;
99+
return reval;
100+
}
101+
102+
/// <summary>
103+
/// 获取类型的公共实例属性集合。
104+
/// </summary>
105+
/// <param name="type">要检查的类型。</param>
106+
/// <returns>属性数组 <see cref="System.Reflection.PropertyInfo[]"/>。</returns>
107+
/// <remarks>
108+
/// 等价于 <see cref="System.Reflection.TypeInfo.GetProperties"/> 的行为。
109+
/// </remarks>
110+
/// <exception cref="System.NullReferenceException">当 <paramref name="type"/> 为 <see langword="null"/> 时。</exception>
111+
/// <seealso cref="System.Reflection.PropertyInfo"/>
112+
/// <seealso cref="System.Type.GetProperties()"/>
113+
public static PropertyInfo[] GetProperties(this Type type)
114+
{
115+
var reval = type.GetTypeInfo().GetProperties();
116+
return reval;
117+
}
118+
119+
/// <summary>
120+
/// 按名称获取类型的公共实例属性。
121+
/// </summary>
122+
/// <param name="type">要检查的类型。</param>
123+
/// <param name="name">属性名称,区分大小写。</param>
124+
/// <returns>匹配的 <see cref="System.Reflection.PropertyInfo"/>;未找到时返回 <see langword="null"/>。</returns>
125+
/// <remarks>
126+
/// 当存在多个重名属性(极少见)时,可能产生 <see cref="System.AmbiguousMatchException"/>。
127+
/// </remarks>
128+
/// <exception cref="System.ArgumentNullException">当 <paramref name="name"/> 为 <see langword="null"/> 时。</exception>
129+
/// <exception cref="System.AmbiguousMatchException">当找到多个具有相同名称的属性时。</exception>
130+
/// <seealso cref="System.Reflection.PropertyInfo"/>
131+
/// <seealso cref="System.Type.GetProperty(System.String)"/>
132+
public static PropertyInfo GetProperty(this Type type, string name)
133+
{
134+
var reval = type.GetTypeInfo().GetProperty(name);
135+
return reval;
136+
}
137+
138+
/// <summary>
139+
/// 按名称获取类型的公共实例字段。
140+
/// </summary>
141+
/// <param name="type">要检查的类型。</param>
142+
/// <param name="name">字段名称,区分大小写。</param>
143+
/// <returns>匹配的 <see cref="System.Reflection.FieldInfo"/>;未找到时返回 <see langword="null"/>。</returns>
144+
/// <remarks>
145+
/// 当存在多个重名字段时,可能产生 <see cref="System.AmbiguousMatchException"/>。
146+
/// </remarks>
147+
/// <exception cref="System.ArgumentNullException">当 <paramref name="name"/> 为 <see langword="null"/> 时。</exception>
148+
/// <exception cref="System.AmbiguousMatchException">当找到多个具有相同名称的字段时。</exception>
149+
/// <seealso cref="System.Reflection.FieldInfo"/>
150+
/// <seealso cref="System.Type.GetField(System.String)"/>
151+
public static FieldInfo GetField(this Type type, string name)
152+
{
153+
var reval = type.GetTypeInfo().GetField(name);
154+
return reval;
155+
}
156+
157+
/// <summary>
158+
/// 判断类型是否为枚举类型。
159+
/// </summary>
160+
/// <param name="type">要检查的类型。</param>
161+
/// <returns>若为枚举类型返回 <see langword="true"/>,否则返回 <see langword="false"/>。</returns>
162+
/// <exception cref="System.NullReferenceException">当 <paramref name="type"/> 为 <see langword="null"/> 时。</exception>
163+
/// <seealso cref="System.Enum"/>
164+
public static bool IsEnum(this Type type)
165+
{
166+
var reval = type.GetTypeInfo().IsEnum;
167+
return reval;
168+
}
169+
170+
/// <summary>
171+
/// 按名称获取类型的公共实例方法。
172+
/// </summary>
173+
/// <param name="type">要检查的类型。</param>
174+
/// <param name="name">方法名称,区分大小写。</param>
175+
/// <returns>匹配的 <see cref="System.Reflection.MethodInfo"/>;未找到时返回 <see langword="null"/>。</returns>
176+
/// <remarks>
177+
/// 当存在多个重名方法且无法唯一选择时会抛出 <see cref="System.AmbiguousMatchException"/>。
178+
/// </remarks>
179+
/// <exception cref="System.ArgumentNullException">当 <paramref name="name"/> 为 <see langword="null"/> 时。</exception>
180+
/// <exception cref="System.AmbiguousMatchException">当找到多个具有相同名称的方法时。</exception>
181+
/// <seealso cref="System.Reflection.MethodInfo"/>
182+
/// <seealso cref="System.Type.GetMethod(System.String)"/>
183+
public static MethodInfo GetMethod(this Type type, string name)
184+
{
185+
var reval = type.GetTypeInfo().GetMethod(name);
186+
return reval;
187+
}
188+
189+
/// <summary>
190+
/// 使用参数类型签名获取类型的公共实例方法。
191+
/// </summary>
192+
/// <param name="type">要检查的类型。</param>
193+
/// <param name="name">方法名称。</param>
194+
/// <param name="types">参数类型数组 <see cref="System.Type[]"/>。</param>
195+
/// <returns>匹配的 <see cref="System.Reflection.MethodInfo"/>;未找到时返回 <see langword="null"/>。</returns>
196+
/// <remarks>
197+
/// 传入 <paramref name="types"/> 可用于在重载中进行精确匹配;数组类型请使用 <see cref="System.Type[]"/>;
198+
/// 引用参数类型请使用 <c>System.Type&amp;</c>;指针参数类型请使用 <c>System.Type*</c>。
199+
/// </remarks>
200+
/// <exception cref="System.ArgumentNullException">当 <paramref name="name"/> 或 <paramref name="types"/> 为 <see langword="null"/> 时。</exception>
201+
/// <exception cref="System.AmbiguousMatchException">当找到多个具有相同签名的方法时。</exception>
202+
/// <seealso cref="System.Type[]"/>
203+
/// <seealso cref="System.Type.GetMethod(System.String,System.Type[])"/>
204+
public static MethodInfo GetMethod(this Type type, string name, Type[] types)
205+
{
206+
var reval = type.GetTypeInfo().GetMethod(name, types);
207+
return reval;
208+
}
209+
210+
/// <summary>
211+
/// 使用参数类型签名获取类型的公共构造函数。
212+
/// </summary>
213+
/// <param name="type">要检查的类型。</param>
214+
/// <param name="types">参数类型数组 <see cref="System.Type[]"/>。</param>
215+
/// <returns>匹配的 <see cref="System.Reflection.ConstructorInfo"/>;未找到时返回 <see langword="null"/>。</returns>
216+
/// <remarks>
217+
/// 传入 <paramref name="types"/> 可用于在重载中精确选择构造函数;引用参数类型请使用 <c>System.Type&amp;</c>,指针参数类型请使用 <c>System.Type*</c>。
218+
/// </remarks>
219+
/// <exception cref="System.ArgumentNullException">当 <paramref name="types"/> 为 <see langword="null"/> 时。</exception>
220+
/// <exception cref="System.AmbiguousMatchException">当找到多个具有相同签名的构造函数时。</exception>
221+
/// <seealso cref="System.Reflection.ConstructorInfo"/>
222+
/// <seealso cref="System.Type.GetConstructor(System.Type[])"/>
223+
public static ConstructorInfo GetConstructor(this Type type, Type[] types)
224+
{
225+
var reval = type.GetTypeInfo().GetConstructor(types);
226+
return reval;
227+
}
228+
229+
/// <summary>
230+
/// 判断类型是否为值类型。
231+
/// </summary>
232+
/// <param name="type">要检查的类型。</param>
233+
/// <returns>若为值类型返回 <see langword="true"/>,否则返回 <see langword="false"/>。</returns>
234+
/// <remarks>
235+
/// 包含结构体与枚举;不包含类与接口。
236+
/// </remarks>
237+
/// <seealso cref="System.ValueType"/>
238+
public static bool IsValueType(this Type type)
239+
{
240+
return type.GetTypeInfo().IsValueType;
241+
}
242+
243+
/// <summary>
244+
/// 判断类型是否为类类型(引用类型)。
245+
/// </summary>
246+
/// <param name="type">要检查的类型。</param>
247+
/// <returns>若为类返回 <see langword="true"/>,否则返回 <see langword="false"/>。</returns>
248+
/// <remarks>
249+
/// 该方法封装 <see cref="System.Type.IsClass"/>;对于 <c>struct</c>/<c>enum</c> 返回 <see langword="false"/>。
250+
/// </remarks>
251+
/// <seealso cref="System.Type.IsClass"/>
252+
public static bool IsEntity(this Type type)
253+
{
254+
return type.GetTypeInfo().IsClass;
255+
}
256+
257+
/// <summary>
258+
/// 获取方法的声明(反射)类型。
259+
/// </summary>
260+
/// <param name="method">方法元信息。</param>
261+
/// <returns>该方法的声明类型 <see cref="System.Type"/>。</returns>
262+
/// <exception cref="System.NullReferenceException">当 <paramref name="method"/> 为 <see langword="null"/> 时。</exception>
263+
/// <seealso cref="System.Reflection.MethodInfo.ReflectedType"/>
264+
public static Type ReflectedType(this MethodInfo method)
265+
{
266+
return method.ReflectedType;
267+
}
268+
}

0 commit comments

Comments
 (0)