简体   繁体   中英

System.InvalidCastException error in c# array

I tried to run a program that can read odd and even numbers in an array, but the error that keeps appearing is System.InvalidCastException . Here's the code:

ArrayList Num = new ArrayList();

Console.WriteLine("Enter 5 numbers");

for (int i = 0; 5 > i; i++)
{
    Console.Write((i + 1) + ". ");
    Num.Add(Console.ReadLine());
}

Num.Sort();

Console.Write("Sorted numbers: ");
foreach (string value in Num)
{
    Console.Write(value + " ");
}

Console.ReadLine();

ArrayList odd = new ArrayList();
ArrayList even = new ArrayList();

foreach (int value in Num)
{      
    if (value % 2 != 0)
    {
        odd.Add(value);
    }

    else
    {
        even.Add(value);
    }

}

Console.Write("Odd numbers: ");
foreach (string number in odd)
{
    Console.Write(number + " ");
}

Console.Write("Even numbers: ");
foreach (string numbers in even)
{
    Console.Write(numbers + " ");
}

Console.ReadLine();

The error indicates that my int value code it's value cannot be converted. Can anyone teach me the right way to solve this error?

Ok lets start from the beginning. If you look at the return value of Console.ReadLine then you will see that it returns a string :

Return Value
Type: System.String

ArrayList can contain objects of different types. your code compiles just fine because the Num is masking the differences between the object types.

When you later on try to loop through your ArrayList Num you assume that each element in it is of type int :

foreach (int value in Num)

But it is not ! you have filled it with strings. When the compiler arrives at this line it will try implicitly to cast each element into an int (because you told it so) but a simple cast form string to int results in exactly that exception that you have encountered

Several solutions can be approached here....

1)
You could treat the objects in the loop as the type that they are, namely object . Then in each iteration you could try to convert them into an int using TryParse and if the conversion works you can add them into your lists:

foreach (object value in Num)
{
    int intvalue = 0;

    if (Int32.TryParse(value.ToString(), out intvalue)
    {
        if (intvalue % 2 != 0)
        {
            odd.Add(intvalue);
        }
        else
        {
            even.Add(intvalue);
        }
    }
}

2)
Another possibility would be to convert the number right away when you are reading it from the console and to choose a collection that is suitable for the type in question, namely int . For example a generic List

List<int> Num_Int_List = new List<int>();

for (int i = 0; 5 > i; i++)
{
    Console.Write((i + 1) + ". ");
    if (int.TryParse(Console.ReadLine(), out enteredNumber)
    {
        Num_Int_List.Add(enteredNumber);
    }
    else
    {
        Console.WriteLine("Sorry that was not an integer, try again please");
        i-- // here set the counter to the last step to allow the user to repeat the step
    }
}

Use the same collection List<int> for odd and even and you can use your foreach loop as it is:

List<int> odd = new List<int>();
List<int> even = new List<int>();

Choosing a type-safe collection like a List<int> will help you to sort out incompatibilities with types already at compile time and not at runtime like in your case

I'd suggest you do this like so, parse the number when you read it in, take advantage of the fact that C# is a typed language. Also I'd consider using Generic collections, List and so forth:

List<int> Num = new List<int>();

Console.WriteLine("Enter 5 numbers");

while (Num.Count < 5)
{
    Console.Write((Num.Count + 1) + ". ");

    int result = 0;
    if (int.TryParse(Console.ReadLine(), out result))
    {
        Num.Add(result);
    }
    else
    {
        Console.WriteLine("Please enter a number!!");
    }
}

Num.Sort();

Console.Write("Sorted numbers: ");
foreach (int value in Num)
{
    Console.Write(value + " ");
}

Console.ReadLine();

List<int> odd = new List<int>();
List<int> even = new List<int>();


foreach (int value in Num)
{

    if (value % 2 != 0)
    {
        odd.Add(value);
    }

    else
    {
        even.Add(value);
    }

}

Console.Write("Odd numbers: ");
foreach (int number in odd)
{
    Console.Write(number + " ");
}

Console.Write("Even numbers: ");
foreach (int numbers in even)
{
    Console.Write(numbers + " ");
}


Console.ReadLine();

as somebody write in the comment section i replace ArrayList with List and then you can Parse your string to int.

Here is my code i hope it helps you.

{

        List<string> Num = new List<string>();


        Console.WriteLine("Enter 5 numbers");

        for (int i = 0; 5 > i; i++)
        {
            Console.Write((i + 1) + ". ");
            Num.Add(Console.ReadLine());
        }

        Num.Sort();

        Console.Write("Sorted numbers: ");
        foreach (string value in Num)
        {
            Console.Write(value + " ");
        }

        Console.ReadLine();

        List<string> odd = new List<string>();
        List<string> even = new List<string>();


        foreach (var value in Num)
        {

            if (Int32.Parse(value) % 2 != 0)
            {
                odd.Add(value);
            }

            else
            {
                even.Add(value);
            }

        }

        Console.Write("Odd numbers: ");
        foreach (string number in odd)
        {
            Console.Write(number + " ");
        }

        Console.Write("Even numbers: ");
        foreach (string numbers in even)
        {
            Console.Write(numbers + " ");
        }


        Console.ReadLine();
    }

Problem lies with following code:

foreach (int value in Num)
{
    if (value % 2 != 0)
    {
        odd.Add(value);
    }
    else
    {
        even.Add(value);
    }    
}

You are trying to cast string to int directly, which is not possible. There can be many possible solutions, I have mentioned one below, in which I cast using Convert.ToInt32 the string value .

foreach (var value in Num)
{
    if (Convert.ToInt32(value) % 2 != 0)
    {
        odd.Add(value);
    }
    else
    {
        even.Add(value);
    }
}
ArrayList Num = new ArrayList();

Console.WriteLine("Enter 5 numbers");

for (int i = 0; 5 > i; i++)
{
    Console.Write((i + 1) + ". ");
    Num.Add(Console.ReadLine());
}

Num.Sort();

Console.Write("Sorted numbers: ");
foreach (string value in Num)
{
    Console.Write(value + " ");
}

Console.ReadLine();

ArrayList odd = new ArrayList();
ArrayList even = new ArrayList();
int V;
foreach (string value in Num)
{
    V = int.Parse(value);
    if (V % 2 != 0)
    {
        odd.Add(value);
    }
    else
    {
        even.Add(value);
    }
}

Console.Write("Odd numbers: ");
foreach (string number in odd)
{
    Console.Write(number + " ");
}

Console.Write("Even numbers: ");
foreach (string numbers in even)
{
    Console.Write(numbers + " ");
}

Console.ReadLine();

拜托了

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM