title: C# How to call FieldInfo.SetValue function without manual type conversion
body: <p>I want to save data-class instance to database and load it from database. and I want to generate sql command automatically. so, I think that I need to use dictionary&lt; string, string> so that solve it.</p>
  
  <p>refer my old question : <a href="https://stackoverflow.com/questions/34942178/how-to-convert-2d-string-array-to-2d-int-double-bool-array">How to convert 2D string array to 2D [int, double, bool, ..] array?</a></p>
  
  <p>working process like these.</p>
  
  <ol>
  <li>convert data-class instance to dictionary &lt; string, string>.</li>
  <li>save/load dictionary to/from txt, database, etc.</li>
  <li>convert dictionary to data-class instance</li>
  </ol>
  
  <p>I think I have solved the problem anyway. but I think converting 2D array method is still not a perfect one. I wonder, when I call FieldInfo.SetValue function, is there another way to solve type conversion without using switch/case state like my solution.</p>
  
  <p>help me simplify my code.</p>
  
  <p>Data class like this</p>
  
  <pre><code>        public class DCylinderData
      {
          public int ID;
  
          public int[] Solenoid = new int[2];
          public int[] UpSensor = new int[DEF_MAX_CYLINDER_SENSOR];
          public int[] DownSensor = new int[DEF_MAX_CYLINDER_SENSOR];
  
          public double MovingTime;
  
          public ECylinderType CylinderType;
          public ESolenoidType SolenoidType;
  
          public bool[] boolTest = new bool[3];
          public string[] nameTest = new string[2];
          public int[,] TwoDimension = new int[3,4];
  
          public DCylinderData()
          {
          }
      }
  </code></pre>
  
  <p>main code like this</p>
  
  <pre><code>            // 0. initialize
          DCylinderData cylData = new DCylinderData();
          cylData.ID = 99;
          cylData.MovingTime = 1.1;
          cylData.CylinderType = ECylinderType.UPSTREAM_DOWNSTREAM;
          cylData.Solenoid = new int[]{ 2, 3};
          for (int i = 0; i &lt; 2 ; i++)
          {
              cylData.Solenoid[i] = i + 2;
              cylData.nameTest[i] = $"NameTest_{i}";
          }
          for (int i = 0; i &lt; DEF_MAX_CYLINDER_SENSOR; i++)
          {
              cylData.UpSensor[i] = i * 1;
              cylData.DownSensor[i] = i * 4;
          }
          for (int i = 0; i &lt; cylData.TwoDimension.GetLength(0) ; i++)
          {
              for (int j = 0; j &lt; cylData.TwoDimension.GetLength(1) ; j++)
              {
                  cylData.TwoDimension[i, j] = i * cylData.TwoDimension.GetLength(1) + j;
              }
          }
          cylData.boolTest[0] = true;
          cylData.boolTest[1] = false;
          cylData.boolTest[2] = true;
  
          // 1. Class -&gt; Dictionary
          Dictionary&lt;string, string&gt; fieldBook = new Dictionary&lt;string, string&gt;();
  
          Type type = typeof(DCylinderData);
          FieldInfo[] fields = type.GetFields();
          foreach (FieldInfo field in fields)
          {
              // 1.1 element
              if (field.FieldType.IsValueType)
              {
                  fieldBook.Add(field.Name, field.GetValue(cylData).ToString());
              }
              // 1.2 array
              else if (field.FieldType.IsArray)
              {
                  Array array = (Array)field.GetValue(cylData);
  
                  // 1.2.1 1-D array
                  if (array.Rank == 1)
                  {
                      for (int i = 0; i &lt; array.GetLength(0); i++)
                      {
                          fieldBook.Add($"{field.Name}__{i}", array.GetValue(i).ToString());
                      }
                  }
                  // 1.2.2 2-D array
                  else if (array.Rank == 2)
                  {
                      for (int i = 0; i &lt; array.GetLength(0); i++)
                      {
                          for (int j = 0; j &lt; array.GetLength(1); j++)
                          {
                              fieldBook.Add($"{field.Name}__{i}__{j}", array.GetValue(i, j).ToString());
                          }
                      }
                  }
                  else
                  {
                      WriteLine($"Not support {field.Name}'s array {array.Rank} dimension.");
                  }
              }
              else
              {
                  WriteLine($"Not support to handle {field.Name}'s {field.FieldType.ToString()}");
              }
          }
  
          // 2. print Dictionary
          foreach (KeyValuePair&lt;string, string&gt; item in fieldBook)
          {
              WriteLine($"FieldBook {item.Key} : {item.Value}");
          }
  
          // 3. Dictionary -&gt; Class
          DCylinderData copyData = new DCylinderData();
          foreach (FieldInfo field in fields)
          {
              // 3.1 handle element
              if (field.FieldType.IsValueType &amp;&amp; fieldBook.ContainsKey(field.Name))
              {
                  SetFieldValue(copyData, field, fieldBook[field.Name]);
              }
              // 3.2 handle array
              else if (field.FieldType.IsArray)
              {
                  Array array = (Array)field.GetValue(copyData);
                  string key, value;
  
                  // 3.2.1 1-D array
                  if (array.Rank == 1)
                  {
                      var arr_1d = new string[array.GetLength(0)];
                      for (int i = 0; i &lt; array.GetLength(0); i++)
                      {
                          key = $"{field.Name}__{i}";
                          value = fieldBook.ContainsKey(key) ? fieldBook[key] : "";
                          arr_1d.SetValue(value, i);
                      }
                      SetFieldValue(copyData, field, arr_1d);
                  }
                  // 3.2.1 2-D array
                  else if (array.Rank == 2)
                  {
                      var arr_2d = new string[array.GetLength(0), array.GetLength(1)];
                      for (int i = 0; i &lt; array.GetLength(0); i++)
                      {
                          for (int j = 0; j &lt; array.GetLength(1); j++)
                          {
                              key = $"{field.Name}__{i}__{j}";
                              value = fieldBook.ContainsKey(key) ? fieldBook[key] : "";
                              arr_2d.SetValue(value, i, j);
                          }
                      }
                      SetFieldValue(copyData, field, arr_2d);
                  }
                  else
                  {
                      WriteLine($"Not support {field.Name}'s array {array.Rank} dimension.");
                  }
              }
              // 3.3 not support
              else
              {
                  WriteLine($"Not support to handle {field.Name}'s {field.FieldType.ToString()}");
              }
          }
  
          WriteLine("Press any key to continue");
          ReadLine();
  </code></pre>
  
  <p>and, SetFieldValue Functions like these</p>
  
  <pre><code>        public static void SetFieldValue(Object target, FieldInfo fieldInfo, string value)
      {
          string fieldType = fieldInfo.FieldType.Name;
          fieldType = fieldType.ToLower();
  
          switch (fieldType)
          {
              case "boolean":
                  bool b;
                  fieldInfo.SetValue(target, bool.TryParse(value, out b) ? b : false);
                  break;
  
              case "int32":
                  int n;
                  fieldInfo.SetValue(target, int.TryParse(value, out n) ? n : 0);
                  break;
  
              case "double":
                  double d;
                  fieldInfo.SetValue(target, double.TryParse(value, out d) ? d : 0);
                  break;
  
              case "string":
                  fieldInfo.SetValue(target, value);
                  break;
          }
      }
  
      public static void SetFieldValue(Object target, FieldInfo fieldInfo, string[] arr)
      {
          string fieldType = fieldInfo.FieldType.Name;
          fieldType = fieldType.ToLower();
          fieldType = fieldType.Replace("[]", "");
  
          switch (fieldType)
          {
              case "boolean":
                  bool b;
                  bool[] arr_b = Array.ConvertAll(arr, s =&gt; bool.TryParse(s, out b) ? b : false);
                  fieldInfo.SetValue(target, arr_b);
                  break;
  
              case "int32":
                  int n;
                  int[] arr_n = Array.ConvertAll(arr, s =&gt; int.TryParse(s, out n) ? n : 0);
                  //int[] arr_n1 = Array.ConvertAll(arr, int.Parse);
                  //int[] arr_n2 = arr.Select(s =&gt; int.TryParse(s, out n) ? n : 0).ToArray();
                  fieldInfo.SetValue(target, arr_n);
                  break;
  
              case "double":
                  double d;
                  double[] arr_d = Array.ConvertAll(arr, s =&gt; double.TryParse(s, out d) ? d : 0);
                  fieldInfo.SetValue(target, arr_d);
                  break;
  
              case "string":
                  fieldInfo.SetValue(target, arr);
                  break;
          }
      }
  
      public static void SetFieldValue(Object target, FieldInfo fieldInfo, string[,] arr)
      {
          string fieldType = fieldInfo.FieldType.Name;
          fieldType = fieldType.ToLower();
          fieldType = fieldType.Replace("[,]", "");
  
          // 0. string return
          switch (fieldType)
          {
              case "string":
                  fieldInfo.SetValue(target, arr);
                  return;
                  break;
          }
  
          // 1. initialize
          int n;
          double d;
          bool b;
  
          //object[,] output = new object[arr.GetLength(0), arr.GetLength(1)];
          int[,] output_n = new int[arr.GetLength(0), arr.GetLength(1)];
          bool[,] output_b = new bool[arr.GetLength(0), arr.GetLength(1)];
          double[,] output_d = new double[arr.GetLength(0), arr.GetLength(1)];
  
          // 2. convert
          for (int i = 0; i &lt; arr.GetLength(0); i++)
          {
              for (int j = 0; j &lt; arr.GetLength(1); j++)
              {
                  switch (fieldType)
                  {
                      case "boolean":
                          output_b[i, j] = bool.TryParse(arr[i, j], out b) ? b : false;
                          break;
  
                      case "int32":
                          output_n[i, j] = int.TryParse(arr[i, j], out n) ? n : 0;
                          break;
  
                      case "double":
                          output_d[i, j] = double.TryParse(arr[i, j], out d) ? d : 0;
                          break;
                  }
              }
          }
  
          // 2. setvalue
          //fieldInfo.SetValue(target, output);
          switch (fieldType)
          {
              case "boolean":
                  fieldInfo.SetValue(target, output_b);
                  break;
  
              case "int32":
                  fieldInfo.SetValue(target, output_n);
                  break;
  
              case "double":
                  fieldInfo.SetValue(target, output_d);
                  break;
          }
      }
  </code></pre>
  
  <p>this is all part of my code. </p>