How to initialize type variables in dynamically generated C # code?

I have a T4 template where I would like to generate a .cs file.

I have an array of System.Data.DataColumn , which I would like to use as private variables in my generated code file.

I use ColumnName as the name of the variable, Value as the value of the variable, and DataType as the variable data type.

I am thinking about how to initialize certain variables in this case:

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

I would like to see the output: private System.String col1 = "text";

Variable definition in T4 template:

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

I am thinking of writing a helper method that will return a variable initialization string for common data types. Something like:

 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; } } 

If someone did something like this, could you advise if this is a good idea or can this be done in a more convenient way? Maybe I should read something?

+7
source share
3 answers

This should work fine, although I would make it a general class. Something like

 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 */ } } 

It will be more flexible and reusable. Usage example:

 <# var dataType = new DataType<String>() { Name = "col1", Value = "text" }; #> private <#= dataType.VariableDefinition() #> 
+3
source

Hope this works.

Use ExpandoObject to solve your problem. ExpandoObject definition according to MSDN:

It represents an object whose members can be dynamically added and deleted at runtime.

To set the data type and value at run time, use the Convert.ChangeType method. This creates an object of the same type and value that you provide.

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

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

Create properties dynamically using ExpandoObject and dynamically create a data type using Convert.ChangeType.

The code:

 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
source

Define a dictionary:

 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) } }; 

Then write this method:

 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))); } 

And call it that:

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

Or even (not very many times):

 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))); } 

FROM

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

All Articles