2013-04-23 6 views
7

私は.csファイルを生成したいT4テンプレートを持っています。動的に生成された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"、テキストは@ "" "Text" ""などです。コンパイラは、生成されたC#コードをコンパイルするときに変換エラーを検出します。 – FuleSnabel

+0

私は変数を定義するために使用するフィールドの着信セットが頻繁に変更されるため、コンパイルエラーは見たくありません。 – Sergejs

答えて

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を使用して問題を解決してください。 MSDNのExpandoObjectの定義:

実行時にメンバを動的に追加および削除できるオブジェクトを表します。

実行時にデータ型と値を設定するには、Convert.ChangeTypeメソッドを使用します。 これは、指定したのと同じ型と値のオブジェクトを作成します。 ExpandoObjectため

参考:Convert.ChangeTypeため https://blogs.msdn.microsoft.com/csharpfaq/2009/09/30/dynamic-in-c-4-0-introducing-the-expandoobject/

参考: 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") #> 
関連する問題