1 Star 6 Fork 1

痴者工良/反射与特性

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
解析泛型.cs 8.05 KB
一键复制 编辑 原始数据 按行查看 历史
痴者工良 提交于 2020-07-26 18:33 . update 解析泛型.cs.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace BindingFlagsSnippet
{
public enum Color
{
Red = 0,
Yellow = 1,
Blue = 2,
Orange = 3,
None = 4
}
public class BaseClass { }
public interface BaseInterFace { }
public class MyClass<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>
where T1 : struct
where T2 : class
where T3 : notnull
where T4 : unmanaged
where T5 : new()
where T6 : BaseClass
where T7 : BaseInterFace
where T8 : T2
// 组合条件
where T9 : class, new()
where T10 : BaseClass, BaseInterFace, new()
{
}
class Example
{
// 解析一个泛型类型,并且解析约束
public static string GetGenericString(Type type)
{
if (!type.IsGenericType)
return type.Name;
string className = type.Name.Split("`")[0] + "<";
Type[] types = ((System.Reflection.TypeInfo)type).GenericTypeParameters;
for (int i = 0; i < types.Length; i++)
{
className += types[i].Name;
if (i + 1 < types.Length)
className += ",";
}
className += "> ";
foreach (var item in types)
{
string str = "where ";
str += item.Name + " : ";
Type[] genericTypes = item.GetGenericParameterConstraints();
GenericParameterAttributes genricAttrs = item.GenericParameterAttributes;
int length = genericTypes.Length - 1;
// 不具有任何约束
if (genericTypes.Length == 0 && genricAttrs == GenericParameterAttributes.None && item.GetCustomAttributes().ToArray().Length == 0)
str = String.Empty;
// 只有一种约束的情况下
// 符号条件有 staruct、unmanaged、<基类名>、<接口名>、T:U
else if (genericTypes.Length == 1)
str += GetGenericType(genericTypes[0]).Item1;
// 没有 Type 约束时
else if (genericTypes.Length == 0)
str += GetGenericType(genricAttrs).Item1;
// 类型约束和特殊标识约束一起时,最麻烦了
// 他们有组合关系,又有顺序关系
// 分为三个顺序阶段,黄色,蓝色,橙
else
{
List<string> color = new List<string>();
// 黄色
bool a = IsHasYellow(genericTypes);
bool b = IsHasYellow(genricAttrs);
if (a == true)
color.Add(genericTypes.FirstOrDefault(x => !x.IsInterface && x.IsSubclassOf(typeof(System.Object))).Name);
else if (b == true)
color.Add(GetGenericType(genricAttrs).Item1);
else color.Add(string.Empty);
// 蓝色
color.Add(GetGenericType(genericTypes.Where(x => !(!x.IsInterface && x.IsSubclassOf(typeof(System.Object)))).ToArray()));
// 橙色
if (genricAttrs.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint))
color.Add(GetGenericType(genricAttrs).Item1);
str += string.Join(",", color.ToArray());
}
className += str + " ";
}
return className;
}
// 枚举值为 8,16 时
// 判断是 struct 还是 unamaged
// 红色
public static string GetStructUnmanaged(Type type)
{
if (type.IsSecurityCritical)
return "struct";
return "unmanaged";
}
// 枚举值为 4 时
// 黄色
public static string GetClass()
{
return "class";
}
/// <summary>
/// 判断是否有黄色
/// </summary>
/// <returns></returns>
public static bool IsHasYellow(Type[] types)
{
return types.Any(x => !x.IsInterface && x.IsSubclassOf(typeof(System.Object)));
}
/// <summary>
/// 判断是否有黄色
/// </summary>
/// <returns></returns>
public static bool IsHasYellow(GenericParameterAttributes attributes)
{
return
attributes == GenericParameterAttributes.ReferenceTypeConstraint ||
attributes == GenericParameterAttributes.None ?
true : false;
}
/// <summary>
/// struct,<基类>,<接口>,T:U
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static (string, Color) GetGenericType(Type type)
{
// 约束也可以是泛型,这里不做处理
if (type.Name == "ValueType")
return ("struct", Color.Red);
else if (type.IsInterface)
return (type.Name, Color.Blue);
else if (type.IsSubclassOf(typeof(Object)))
{
return (type.Name, Color.Yellow);
}
else
return (type.Name, Color.Blue);
}
/// <summary>
/// 多种组合条件,struct,<基类>,<接口>,T:U
/// </summary>
/// <param name="types"></param>
/// <returns></returns>
public static string GetGenericType(Type[] types)
{
int length = types.Length - 1;
string str = "";
for (int i = 0; i <= length; i++)
{
// 约束也可以是泛型,这里不做处理
if (types[i].Name == "ValueType")
str += "struct";
else
str += types[i].Name;
if (i < length)
str += ",";
}
return str;
}
/// <summary>
/// 单个或多个组合条件, class、notnull、new()
/// </summary>
/// <param name="attributes"></param>
/// <returns></returns>
public static (string, Color) GetGenericType(GenericParameterAttributes attributes)
{
/*
* 下面是不同约束的结果
* class:ReferenceTypeConstraint
* notnull:None
* unmanaged:NotNullableValueTypeConstraint, DefaultConstructorConstraint
* new():DefaultConstructorConstraint
*/
switch (attributes)
{
case GenericParameterAttributes.ReferenceTypeConstraint:
return ("class", Color.Yellow);
case GenericParameterAttributes.None:
return ("notnull", Color.Yellow);
case GenericParameterAttributes.DefaultConstructorConstraint:
return ("new()", Color.Orange);
// 多种组合条件时
default:
string str = "";
if (attributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint))
str += "class,";
if (attributes.HasFlag(GenericParameterAttributes.None))
str += "notnull,";
if (attributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint))
str += "new(),";
// 去除最后一个 , 号,
return (str.Substring(0, str.Length - 1), Color.None);
}
}
static void Main()
{
Type type = typeof(MyClass<,,,,,,,,,,>);
Console.WriteLine(GetGenericString(type));
Console.ReadKey();
}
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C#
1
https://gitee.com/whuanle/reflection_and_properties.git
git@gitee.com:whuanle/reflection_and_properties.git
whuanle
reflection_and_properties
反射与特性
master

搜索帮助