views:

50

answers:

2

So I'm building an application that is going to do a ton of code generation with both C# and VB output (depending on project settings).

I've got a CodeTemplateEngine, with two derived classes VBTemplateEngine and CSharpTemplateEngine. This question regards creating the property signatures based on columns in a database table. Using the IDataReader's GetSchemaTable method I gather the CLR type of the column, such as "System.Int32", and whether it IsNullable. However, I'd like to keep the code simple, and instead of having a property that looks like:

    public System.Int32? SomeIntegerColumn { get; set; }

or

    public Nullable<System.Int32> SomeIntegerColumn { get; set; },

where the property type would be resolved with this function (from my VBTemplateEngine),

    public override string ResolveCLRType(bool? isNullable, string runtimeType)
    {
        Type type = TypeUtils.ResolveType(runtimeType);
        if (isNullable.HasValue && isNullable.Value == true && type.IsValueType)
        {
            return "System.Nullable(Of " + type.FullName + ")";
            // or, for example...
            return type.FullName + "?";
        }
        else
        {
            return type.FullName;
        }
    },

I would like to generate a simpler property. I hate the idea of building a Type string from nothing, and I would rather have something like:

    public int? SomeIntegerColumn { get; set; }

Is there anything built-in anywhere, such as in the VBCodeProvider or CSharpCodeProvider classes that would somehow take care of this for me?

Or is there a way to get a type alias of int? from a type string like System.Nullable'1[System.Int32]?

Thanks!

UPDATE:

Found something that would do, but I'm still wary of that type of mapping of Type full names to their aliases.

+2  A: 

There are two issues here:

  1. System.Int32 has the C# alias int, which you prefer.
  2. System.Nullable can be indicated using a ? symbol in C#, which you prefer.

There are no methods included with the .NET Framework to take these into account when converting the type name to a string. You are going to have to roll your own.

binarycoder
That's what I figured. Thanks for the quick reply.
Cory Larson
<That's what I figured.> I considered writing some code, but from your post, it looks like you've mostly got it figured out already.
binarycoder
The CodeDomProvider.GetTypeOutput method takes account of #1. You're right about #2 though as far as I know.
itowlson
+2  A: 

You can do this using CodeDom's support for generic types and the GetTypeOutput method:

CodeTypeReference ctr;
if (/* you want to output this as nullable */)
{
  ctr = new CodeTypeReference(typeof(Nullable<>));
  ctr.TypeArguments.Add(new CodeTypeReference(typeName));
}
else
{
  ctr = new CodeTypeReference(typeName);
}
string typeName = codeDomProvider.GetTypeOutput(ctr);

This will respect language-specific type keywords such as C# int or VB Integer, though it will still give you System.Nullable<int> rather than int?.

itowlson
This will get me about half-way there, which is better than what I started with. I'll try it out tonight and let you know my thoughts. Thanks!
Cory Larson
Although this method may not be ideal for everyone, it suits me and answers my questions of "is there another way." Thanks!
Cory Larson