Type.GetType(string)使用“Generic <t>”语法?</t>

时间:2009-05-24 02:53:51

标签: c# asp.net generics reflection

我正在构建一个通用的ASP.NET服务器控件,它具有用于指定类型名称的属性。我正在使用控件生成器通过将属性值传递给Type.GetType(string)来生成控件的通用版本。这非常有效。但是,如果我要指定的类型是通用的,我必须使用如下语法:

<gwb:GenericControl runat="server" 
    TypeName="System.Collections.Generic.List`1[System.String]" />

我希望能够像这样输入:

<gwb:GenericControl runat="server"
    TypeName="System.Collections.Generic.List<System.String>" />

我知道我可以手动解析尖括号的值并将它们转换为方括号,并添加相应的反引号数字前缀,但是我想知道是否有任何内置方法来执行此转换?我认为Generic<T>语法特定于C#(或至少在VB.NET中不同)所以我猜我还必须解析任何其他语言特定的语法。

我注意到ASP.NET MVC在Inherits指令的Page属性中执行此操作,但我不确定如何。

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
    Inherits="System.Web.Mvc.ViewPage<MyModel>" %>

3 个答案:

答案 0 :(得分:5)

不,没有内置的方法可以做到这一点。原因是像Generic<T>这样的类型名称确实特定于C#。实际上,它们在元数据中的写法不同。

简短版本是类型名称,后跟一个`,然后是一个与通用参数计数相对应的数字。例如,Generic<T>将被写为Generic`1,而Generic<T1,T2>将被写为Generic`2。数组为语法添加了一些复杂性,但这是一般规则。

当您使用Type.GetType时,您实际上在进行MetaData查询而不是C#查询。因此必须提供类型名称,因为它出现在MetaData中。

答案 1 :(得分:2)

没有内置的方法可以做到这一点。你需要解析它。这可能是MVC框架在内部所做的事情。

答案 2 :(得分:1)

您实际上无法使用该特定语法。由于xml的性质,您的实际语法必须如下:

<gwb:GenericControl runat="server"
    TypeName="System.Collections.Generic.List&lt;System.String>" />

你不能使用&lt;如果对应的&gt;属性值内的字符存在。你必须用&amp; lt;对它进行编码,这种方法在第一时间就试图让它像那样工作。

第一种形式是标准的IL形式(即Namespace.GenericClass`1 [[System.String]]),对任何精通的.NET语言用户都应该有点熟悉,并且全面通用,而第二种形式只有效对于C#。