1 Unstar Star 0 Fork 0

痴者工良 / 反射与特性C#

Create your Gitee Account
Explore and code with more than 5 million developers,Free private repositories !:)
Sign up
This repository doesn't specify license. Without author's permission, this code is only for learning and cannot be used for other purposes.
Nothing here. spread retract

Clone or download
解析泛型.cs 8.05 KB
Copy Edit Web IDE Raw Blame History
痴者工良 authored 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();
}
}
}

Comment ( 0 )

Sign in for post a comment

C#
1
https://gitee.com/whuanle/reflection_and_properties.git
git@gitee.com:whuanle/reflection_and_properties.git
whuanle
reflection_and_properties
反射与特性
master

Search

131423 f1aaba0b 1899542 094922 1c74bed3 1899542