1

My Goal is these.

  1. convert data class to dictionary.
  2. save/load that dictionary to/from txt, database, etc.
  3. convert dictionary to data class

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].

4 Answers 4

3

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]);
    }
}
Sign up to request clarification or add additional context in comments.

10 Comments

do you really need to TryParse instead of Parse there?
@bashis That depends on your specific needs. Are you 100% sure the values can be parsed correctly and what should happen if they're not? TryParse will fill in 0, Parse will throw an exception.
yeah, and with this approach you will have no chance to figure out if zeroes in the result were actually zeroes in the original array. I don't think this is the desirable behaviour in most cases.
@bashis If the results are meant to be nullable ints, then definitely consider revising. Otherwise you'll need a default of some sort and most of the time that's 0.
@Balah it all depends on the use-case, of course, but I strongly believe that throwing an exception with Parse is almost always a better option than returning default zeroes.
|
1

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

1 Comment

Thanks, but My problem is not ToStringArray, but FromStringArray.
0

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

Comments

0

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.

3 Comments

Thanks for your help. when execute your code "fieldInfo.SetValue(target, output);", an exception is occured. that exception is 'ArgumentExcption was unhandled', because fieldInfo.SetValue method is not support automatic cast from object type to specific type. and i cant call the method like this "fieldInfo.SetValue(target, (fieldInfo.FieldType)output" so, maybe i must preallocate each type's array variable for this problem.
and what i'm not using serializer is automatically create sql command for save/load data on database by using dictionary<string,string>. if just support save/load data on file format, maybe I choose serializer function. As I am newbie on c#, if there is anything not correct, tell me what i'm wrong.
The code is full of errors (it was more of a thought process, than a working solution). I will update it now. For serializing, look at the answer to this question. That will allow you to save/load data of file format/database, or any source: stackoverflow.com/questions/4021893/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.