如何解析C#泛型类型名称?
发布时间:2020-12-15 07:44:01 所属栏目:百科 来源:网络整理
导读:如何解析格式为List int的C#样式泛型类型名称?或字典 string,int甚至更复杂的Dictionary string,Dictionary System.String,int [].假设这些名称是字符串,实际上可能不代表现有类型.它应该能够很容易地解析BogusClass A,B,Vector C.为了清楚起见,我对解析格
|
如何解析格式为List< int>的C#样式泛型类型名称?或字典< string,int>甚至更复杂的Dictionary< string,Dictionary< System.String,int []>>.假设这些名称是字符串,实际上可能不代表现有类型.它应该能够很容易地解析BogusClass< A,B,Vector< C>>.为了清楚起见,我对解析格式为List`1 [[System.Int32]]的.NET内部类型名称不感兴趣,但实际的C#类型名称就像它们出现在源代码中一样,有或没有使用点的命名空间限定符符号.
正则表达式是因为这些是嵌套结构.我想也许System.CodeDom.CodeTypeReference构造函数会为我解析它,因为它有字符串BaseType和CodeTypeReferenceCollection TypeArguments成员,但那些显然需要手动设置. CodeTypeReference是我需要的一种结构: class TypeNameStructure
{
public string Name;
public TypeNameStructure[] GenericTypeArguments;
public bool IsGenericType{get;}
public bool IsArray{get;} //would be nice to detect this as well
public TypeNameStructure( string friendlyCSharpName )
{
//Parse friendlyCSharpName into name and generic type arguments recursively
}
}
框架中是否有任何现有的类来实现这种类型名称解析?如果没有,我将如何解析这个? 解决方法
回答自己的问题.我写了下面的类来实现我需要的结果;给它一个旋转.
public class TypeName
{
public string Name;
public bool IsGeneric;
public List<ArrayDimension> ArrayDimensions;
public List<TypeName> TypeArguments;
public class ArrayDimension
{
public int Dimensions;
public ArrayDimension()
{
Dimensions = 1;
}
public override string ToString()
{
return "[" + new String(',',Dimensions - 1) + "]";
}
}
public TypeName()
{
Name = null;
IsGeneric = false;
ArrayDimensions = new List<ArrayDimension>();
TypeArguments = new List<TypeName>();
}
public static string MatchStructure( TypeName toMatch,TypeName toType )
{
return null;
}
public override string ToString()
{
string str = Name;
if (IsGeneric)
str += "<" + string.Join( ",",TypeArguments.Select<TypeName,string>( tn => tn.ToString() ) ) + ">";
foreach (ArrayDimension d in ArrayDimensions)
str += d.ToString();
return str;
}
public string FormatForDisplay( int indent = 0 )
{
var spacing = new string(' ',indent );
string str = spacing + "Name: " + Name + "rn" +
spacing + "IsGeneric: " + IsGeneric + "rn" +
spacing + "ArraySpec: " + string.Join( "",ArrayDimensions.Select<ArrayDimension,string>( d => d.ToString() ) ) + "rn";
if (IsGeneric)
{
str += spacing + "GenericParameters: {rn" + string.Join( spacing + "},{rn",string>( t => t.FormatForDisplay( indent + 4 ) ) ) + spacing + "}rn";
}
return str;
}
public static TypeName Parse( string name )
{
int pos = 0;
bool dummy;
return ParseInternal( name,ref pos,out dummy );
}
private static TypeName ParseInternal( string name,ref int pos,out bool listTerminated )
{
StringBuilder sb = new StringBuilder();
TypeName tn = new TypeName();
listTerminated = true;
while (pos < name.Length)
{
char c = name[pos++];
switch (c)
{
case ',':
if (tn.Name == null)
tn.Name = sb.ToString();
listTerminated = false;
return tn;
case '>':
if (tn.Name == null)
tn.Name = sb.ToString();
listTerminated = true;
return tn;
case '<':
{
tn.Name = sb.ToString();
tn.IsGeneric = true;
sb.Length = 0;
bool terminated = false;
while (!terminated)
tn.TypeArguments.Add( ParseInternal( name,out terminated ) );
var t = name[pos-1];
if (t == '>')
continue;
else
throw new Exception( "Missing closing > of generic type list." );
}
case '[':
ArrayDimension d = new ArrayDimension();
tn.ArrayDimensions.Add( d );
analyzeArrayDimension: //label for looping over multidimensional arrays
if (pos < name.Length)
{
char nextChar = name[pos++];
switch (nextChar)
{
case ']':
continue; //array specifier terminated
case ',': //multidimensional array
d.Dimensions++;
goto analyzeArrayDimension;
default:
throw new Exception( @"Expecting ""]"" or "","" after ""["" for array specifier but encountered """ + nextChar + @"""." );
}
}
throw new Exception( "Expecting ] or,after [ for array type,but reached end of string." );
default:
sb.Append(c);
continue;
}
}
if (tn.Name == null)
tn.Name = sb.ToString();
return tn;
}
}
如果我运行以下内容: Console.WriteLine( TypeName.Parse( "System.Collections.Generic.Dictionary<Vector<T>,int<long[]>[],bool>" ).ToString() ); 它正确地生成以下输出,将TypeName表示为字符串: Name: System.Collections.Generic.Dictionary
IsGeneric: True
ArraySpec:
GenericParameters: {
Name: Vector
IsGeneric: True
ArraySpec:
GenericParameters: {
Name: T
IsGeneric: False
ArraySpec:
}
},{
Name: int
IsGeneric: True
ArraySpec: []
GenericParameters: {
Name: long
IsGeneric: False
ArraySpec: []
}
},{
Name: bool
IsGeneric: False
ArraySpec:
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
