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.

Cᴏʀʏ
  • 105,112
  • 20
  • 162
  • 194

2 Answers2

4

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
  • 73,686
  • 17
  • 161
  • 157
  • 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! – Cᴏʀʏ Mar 17 '10 at 18:53
  • Although this method may not be ideal for everyone, it suits me and answers my questions of "is there another way." Thanks! – Cᴏʀʏ Mar 19 '10 at 04:08
2

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.

Jason Kresowaty
  • 16,105
  • 9
  • 57
  • 84