2016-01-22 111 views
1

我的目标是这些。如何将2D字符串数组转换为2D [int,double,bool,..]数组?

  1. 将数据类转换为字典。
  2. 保存/那本字典/从TXT,数据库负载等
  3. 转换字典数据类

我想我解决了alomost,但一个问题仍然remail。

问题是将2d字符串数组转换为2d它是原始数据类型数组。

我已成功将字符串转换为原始数据类型。 这样

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

我已经成功转换1D字符串数组到1d原始数据类型的数组。 这样的

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 => bool.TryParse(s, out b) ? b : false); 
       fieldInfo.SetValue(target, arr_b); 
       break; 

      case "int32": 
       int n; 
       int[] arr_n = Array.ConvertAll(arr, s => int.TryParse(s, out n) ? n : 0); 
       //int[] arr_n1 = Array.ConvertAll(arr, int.Parse); 
       //int[] arr_n2 = arr.Select(s => 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 => 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("[,]", ""); 

     int n; 
     double d; 
     bool b; 
     switch (fieldType) 
     { 
      case "boolean": 
       //bool[] arr_b = Array.ConvertAll(arr, s => bool.TryParse(s, out b) ? b : false); 
       //fieldInfo.SetValue(target, arr_b); 
       break; 

      case "int32": 
       //int[,] arr_n = Array.ConvertAll(arr, s => int.TryParse(s, out n) ? n : 0); 
       //fieldInfo.SetValue(target, arr_n); 
       break; 

      case "double": 
       //double[,] arr_d = Array.ConvertAll(arr, s => double.TryParse(s, out d) ? d : 0); 
       //fieldInfo.SetValue(target, arr_d); 
       break; 

      case "string": 
       fieldInfo.SetValue(target, arr); 
       break; 
     } 
    } 

和,我需要解决这个问题是因为我无法获取GetType()。GetField的数组位置。我放弃了获取数组[行,列]的数组[第n,m_th]的GetField。

回答

1

请参考下面的示例代码,并将其应用于您的代码。

static string[,] ToStringArray(object arg) 
{ 
    string[,] result = null; 

    if (arg is Array) 
    { 
     int rank = ((Array)arg).Rank; 
     if (rank == 2) 
     { 
      int columnCount = ((Array)arg).GetUpperBound(0); 
      int rowCount = ((Array)arg).GetLength(0); 
      result = new string[rowCount, columnCount]; 

      for (int i = 0; i < rowCount; i++) 
      { 
       for (int j = 0; j < columnCount; j++) 
       { 
        result[i, j] = ((Array)arg).GetValue(i, j).ToString(); 
       } 
      } 
     } 
    } 

    return result; 
} 
+0

谢谢,但我的问题不是ToStringArray,而是FromStringArray。 – yeminfa

2

最简单的方法是只在阵列上环:

string[,] strings = new string[,] { { "1", "2", "3" }, { "4", "5", "6" } }; 
int[,] ints = new int[strings.GetLength(0), strings.GetLength(1)]; 

for (int i = 0; i < strings.GetLength(0); i++) 
{ 
    for (int j = 0; j < strings.GetLength(1); j++) 
    { 
     int.TryParse(strings[i, j], out ints[i, j]); 
    } 
} 
+0

你确实需要'TryParse'而不是'Parse'吗? – bashis

+0

@bashis这取决于您的具体需求。你是否100%确定这些值可以被正确解析,如果它们不是,会发生什么? 'TryParse'会填0,'Parse'会抛出异常。 – user1793963

+0

是的,用这种方法,你将没有机会找出结果中的零是否在原始数组中实际为零。在大多数情况下,我认为这不是理想的行为。 – bashis

0

看起来你几乎没有。你可以尝试这样的事情:

您的类似功能的东西改为@ user1793963的answer,创建动态阵列中有一个switch语句(这将使它成为任何类型的),并把case语句内循环。所以它看起来就像下面:

public static void SetFieldValue(Object target, FieldInfo fieldInfo, string[,] arr) 
{ 
    string fieldType = fieldInfo.FieldType.Name; 
    fieldType = fieldType.ToLower(); 
    fieldType = fieldType.Replace("[,]", ""); 

    int n; 
    double d; 
    bool b; 
    dynamic output; 

    // this should be in a different method 
    switch (fieldType) 
    { 
     case "boolean": 
      output = new bool[arr.GetLength(0), arr.GetLength(1)]; 
      break; 

     case "int32": 
      output = new int[arr.GetLength(0), arr.GetLength(1)]; 
      break; 

     case "double": 
      output = new double[arr.GetLength(0), arr.GetLength(1)]; 
      break; 

     default: 
      output = new string[arr.GetLength(0), arr.GetLength(1)]; 
      break; 
    } 

    for (int i = 0; i < arr.GetLength(0); i++) 
    { 
     for (int j = 0; j < arr.GetLength(1); j++) 
     { 
      switch (fieldType) 
      { 
       case "boolean": 
        output[i, j] = bool.TryParse(arr[i, j], out b) ? b : false; 
        break; 

       case "int32": 
        output[i, j] = int.TryParse(arr[i, j], out n) ? n : 0; 
        break; 

       case "double": 
        output[i, j] = double.TryParse(arr[i, j], out d) ? d : 0; 
        break; 

       default: 
        output[i, j] = arr[i, j]; 
        break; 
      } 
     } 
    } 

    fieldInfo.SetValue(target, output); 
} 

在一个侧面说明,因为你序列化我只是使用一个JavaScriptSerializerXmlSerializer或使用BinaryFormatter(首选方法使用Newtonsoft JSON.Net。)深入克隆,那么你不需要手动进行所有的转换。这个问题在这里对如何序列化字典有一个很好的答案:Saving a Dictionary<String, Int32> in C# - Serialization?


如果仍然不能解决问题,更新随你怎么叫SetFieldValue你的问题,所以我们可以看到发生了什么。

+0

感谢您的帮助。当执行你的代码“fieldInfo.SetValue(target,output);”时,发生异常。该异常是'ArgumentExcption未处理',因为fieldInfo.SetValue方法不支持从对象类型自动转换为特定类型。我不能调用这样的方法“fieldInfo.SetValue(目标,(fieldInfo.FieldType)输出” 所以,也许我必须预先分配每个类型的数组变量这个问题。 – yeminfa

+0

和什么我不使用序列化是自动创建SQL使用dictionary 命令来保存/加载数据库上的数据,如果只是支持保存/加载文件格式的数据,可能我选择了serializer函数,因为我是c#的新手,如果有什么不正确的,告诉我 – yeminfa

+0

这段代码充满了错误(它更像是一个思考过程,而不是一个可行的解决方案),现在我会更新它,对于序列化,请看这个问题的答案。保存/加载文件格式/数据库或任何来源的数据:http://stackoverflow.com/questions/4021893/saving-a-dictionarystring-int32-in-c-sharp-serialization – Balah

0

因为fieldInfo.SetValue函数不支持隐式转换,所以我需要为每个数据类型分配数组,即使我不需要。 所以,这是我的方法。感谢您的帮助,Balah,user1793963。

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 < arr.GetLength(0); i++) 
     { 
      for (int j = 0; j < 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; 
     } 
    } 
相关问题