views:

1333

answers:

3

I'm building a generic ASP.NET server control that has an attribute used to specify a type name. I'm using a control builder to generate the generic version of my control by passing the attribute value to Type.GetType(string). This works great. However, if the type that I want to specify is generic, I have to use syntax like this:

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

I'd like to be able to type it like this:

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

I know I could manually parse the value for angle brackets and convert them to square brackets, and add in the appropriate backtick-numeric prefix, but I was wondering if there was any built-in way to do this conversion? I assume the Generic<T> syntax is specific to C# (or at least different in VB.NET) so I'm guessing I'd also have to parse any other language-specific syntax.

I've noticed that ASP.NET MVC does this in the Inherits attribute of the Page directive, but I'm not sure how.

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

There's no built-in way of doing this. You need to parse it out. This is probably what the MVC framework is doing internally.

ichiban
+5  A: 

No, there is no built-in way of doing this. The reason why is that type names like Generic<T> are indeed specific to C#. They are actually written out differently in metadata.

The short version is that it will be the type name, followed by a ` and then a number corresponding with the count of generic parameters. Generic<T> for instance will be written out as Generic`1 and Generic<T1,T2> will be written out as Generic`2. Arrays add a bit of complication to the syntax but it's the general rule.

When you use Type.GetType you are actually doing a MetaData query vs. a C# query. So the type name must be provided as it appears in MetaData.

JaredPar
+1  A: 

You won't actually be able to use that specific syntax. Your actual syntax would have to be the following due to the nature of xml:

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

You can't use the < character within the value of an attribute if its corresponding > is present. You must encode it with &lt;, which kind of defeats the point of trying to make it work like that in the first place.

The first form is standard IL form (i.e. Namespace.GenericClass`1[[System.String]]) and should be somewhat familiar to any versed .NET language user, and common across the board, while the second is only valid for C#.

jrista
Wouldn't the ASP.NET MVC framework be violating this rule as well, or is the Page directive not considered part of the XML document?
GWB
The Page directive isn't part of the XML document. The <%@ and %> wrapping it kind of put it in the category of inline code, like the stuff between the obligatory <% %>, which is all handled by the ASPX compiler. It's all processed and either stripped out or turned into more markup before the page is sent through an xml validator.
jrista