2013-04-23 35 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") #>