GWB
GWB

Reputation: 2605

Type.GetType(string) using "Generic<T>" syntax?

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>" %>

Upvotes: 3

Views: 2807

Answers (3)

jrista
jrista

Reputation: 32960

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#.

Upvotes: 1

JaredPar
JaredPar

Reputation: 754763

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.

Upvotes: 5

ichiban
ichiban

Reputation: 6200

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.

Upvotes: 2

Related Questions