Reputation: 13
My Goal is these.
I think I solved alomost, but one problem still remail.
the problem is that convert 2d string array to 2d it's original datatype array.
I have succeeded convert string to original datatype. like this
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;
}
}
I have succeeded convert 1d string array to 1d original datatype array. like this
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;
}
}
but, what should i do when handle 2D array?
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;
}
}
and, what i need to solve this problem is because I can't get GetType().GetField of array position. I gave up to get GetField of array[n_th,m_th] of array[row,col].
Upvotes: 1
Views: 1811
Reputation: 2540
Looks like you were nearly there. You can try something like this:
Change your function something similar to @user1793963's answer, create a dynamic array in one switch statement (which will allow it to be of any type) and put the case statements inside the loop. so it will look like the below:
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);
}
On a side-note, since you're serializing I'd just use either a JavaScriptSerializer
(preferred method. use Newtonsoft JSON.Net), XmlSerializer
or use a BinaryFormatter
to deep clone then you won't need to do all the conversions back and forth manually. This question over here has a good answer on how to serialize dictionaries: Saving a Dictionary<String, Int32> in C# - Serialization?.
If that still does not help, update your question with how you call SetFieldValue
so we can see what is happening.
Upvotes: 0
Reputation: 13
Because fieldInfo.SetValue function do not support implicit conversion, I need to allocate arrays for each data type even though i don't want. so, here is my method. thanks for your help, 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;
}
}
Upvotes: 0
Reputation: 1335
The easiest way is to just loop over the array:
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]);
}
}
Upvotes: 3
Reputation: 1267
Please Refer following sample code, and apply it your code.
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;
}
Upvotes: 1