2013-04-23 38 views
7

我有T4模板,我想生成一个.cs文件。如何初始化动态生成的C#代码中的各种类型变量?

我有System.Data.DataColumn数组,我想在我的生成的代码文件中的私有变量使用。

我使用ColumnName作为变量名称,Value作为变量值,DataType作为可变数据类型。

我想对我怎么在这种情况下初始化定义的变量:

ColumnName = "col1" 
ColumnValue = "text" 
DatType = System.String 

我想看到的输出:private System.String col1 = "text";

变量定义在T4模板:

private <#= DataType.ToString() #> <#= ColumnName #> = "<=# ColumnValue #>" 

我在想写作的辅助方法,将返回的通用数据类型变量的初始化字符串。喜欢的东西:

public string ValueInitializerString 
     { 
      get 
      { 

       string valueString; 
       if (this.DataType == typeof(int)) 
       { 
        valueString = this.Value.ToString(); 
       } 
       else if (this.DataType == typeof(string)) 
       { 
        valueString = string.Format("\"{0}\"", this.Value); 
       } 
       else if (this.DataType == typeof(DateTime)) 
       { 
        DateTime dateTime = (DateTime)this.Value; 

        valueString = string.Format("new DateTime({0}, {1}, {2}, {3}, {4}, {5}, {6})", 
                   dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond); 
       } 
       else 
       { 
        throw new Exception(string.Format("Data type {0} not supported. ", this.DataType)); 
       } 
       return valueString; 
      } 
     } 

如果有人做了类似的事情,可能你的意见,如果这是一个好主意,或者它可以在更方便的方式来完成?也许我应该读点什么?

+1

你也可以初始化值应该在结果输出。即:对于int为“0”,对于文本为“@”,“文本”等。编译生成的C#代码时,编译器将检测到任何转换错误。 – FuleSnabel 2013-04-24 05:52:43

+0

问题是传入的字段集合,我用来定义变量会经常更改,所以我不想看到编译错误。 – Sergejs 2013-04-24 08:03:31

回答

3

这应该做工精细,虽然我想使它成为一个通用类。类似于

internal class DataType<T> 
{ 
     public string Name {get;set} 
     public T Value {get;set;} 
     public Type Type 
     { 
      get { return typeof(T); } 
     } 

     public string VariableDefinition() 
     { 
      /* Construct string */ 
     } 
} 

这会更加灵活和可重复使用。用法示例:

<# 
var dataType = new DataType<String>() 
{ 
    Name = "col1", 
    Value = "text" 
}; 
#> 

private <#= dataType.VariableDefinition() #> 
1

希望这能奏效。

使用ExpandoObject解决您的问题。 ExpandoObject的 定义为每MSDN:

它代表一个对象,其构件可被动态地添加和在运行时除去。

要在运行时设置数据类型和值,请使用Convert.ChangeType方法。 这会创建与您提供的相同类型和值的对象。

参考了ExpandoObject: https://blogs.msdn.microsoft.com/csharpfaq/2009/09/30/dynamic-in-c-4-0-introducing-the-expandoobject/

参考了Convert.ChangeType: https://msdn.microsoft.com/en-us/library/system.convert.changetype(v=vs.110).aspx

因此,创建动态使用ExpandoObject性能和动态使用Convert.ChangeType创建数据类型。

代码:

class Program 
{ 
     static void Main(string[] args) 
     { 
     // I have used hardcoded values representing database values 
     var dataTable = new DataTable(); 
     dataTable.Columns.Add(new DataColumn("Column1")); 
     dataTable.Columns.Add(new DataColumn("Column2")); 
     var row = dataTable.NewRow(); 
     row[0] = 1; 
     row[1] = "Test Value"; 
     dataTable.Rows.Add(row); 

     // This list below contains properties - variables , with same datatype and value 
     dynamic parentList = new List<dynamic>(); 

     var rowOne = dataTable.Rows[0]; 
     for (int i = 0; i < dataTable.Columns.Count; i++) 
     { 
      dynamic child= new ExpandoObject(); 

      child.Property = Convert.ChangeType(row[i], row[i].GetType()); 
      parentList.Add(child); 
     } 
    } 

} 
1

定义词典:

var _valueConverters = new Dictionary<Type, Func<object, string>>() 
{ 
    { typeof(int), x => x.ToString() }, 
    { typeof(string), x => "\"" + x + "\"" }, 
    { typeof(DateTime), x => String.Format("new DateTime({0})", ((DateTime)x).Ticks) } 
}; 

然后写一个像这样的方法:

void WriteVariable<T>(string name, string value) 
{ 
    Type typeT = typeof(T); 
    if (! _valueConverters.ContainsKey(typeT)) 
     throw new Exception(string.Format("Data type {0} not supported. ", typeT.Name)); 
    Write(String.Format("{0} {1} = {2}", typeT.Name, name, _valueConverters[typeT](value))); 
} 

,并调用它,这样的:

甚至(不是真正可重复使用):

void WriteVariable<T>(string name, string value) 
{ 
    Type typeT = typeof(T); 
    if (! _valueConverters.ContainsKey(typeT)) 
     throw new Exception(string.Format("Data type {0} not supported. ", typeT.Name)); 
    Write(String.Format("private {0} {1} = {2};", typeT.Name, name, _valueConverters[typeT](value))); 
} 

有了:

<#= WriteVariable<string>("col1", "text") #>