I'd like to print all ten random generated points for each object in the ArrayList AL.
public class Point
{
public int x;
public int y;
public Point(int x, int y)
{
x = this.x;
y = this.y;
}
}
public class ArrayListTest
{
public static void Main(string[] args)
{
ArrayList AL = new ArrayList();
Random Rnd = new Random();
for (int i = 1; i <= 10; i++)
{
Point p = new Point(Rnd.Next(50), Rnd.Next(50));
AL.Add(p);
}
PrintValues(AL);
}
public static void PrintValues(IEnumerable myList)
{
foreach (Object obj in myList)
Console.WriteLine("{0} ", obj);
}
}
Output on console:
Point
Point
Point
Point
Point
Point
Point
Point
Point
Point
My Problem is, that the classname of the object printed and not the values of the objects. I am using .NET Framework v4.8
(Aside: I recommend that you don't define your own class called Point
. It's likely to conflict with a built-in class and cause confusion. You should give your class a different name.)
So, what happens when you do Console.WriteLine(object obj)
is that inside Console.WriteLine()
it ends up calling object.ToString()
to determine the string to write.
By default, if you don't write your own implementation of ToString()
, it will return the name of the class - this is why you are seeing Point
in the output.
Since you are writing your own Point
class, you can override its ToString()
to return a formatted string. This is the best solution.
Assuming that your Point
class has X and Y values, you can do that by adding the following to the class:
public override string ToString()
{
return $"X={x}, Y={y}";
}
If you didn't want to do this (or supposing it was a third-party class that you couldn't change), you would have to format the string explicitly before passing it to Console.WriteLine()
.
Unfortunately, because you are using ArrayList
, you end up with only an object
- so in order to format it you will need to cast it to the correct type in order to get at its X and Y values:
foreach (Object obj in myList)
{
Point p = (Point)obj;
Console.WriteLine("X={0}, Y={1}", p.x, p.y);
}
Or you can take advantage of the fact that a foreach
for an IEnumerable
will do the cast for you if you declare the loop variable as the correct type:
foreach (Point p in myList)
{
Console.WriteLine("X={0}, Y={1}", p.x, p.x);
}
However, much better is to use List<Point>
rather than an ArrayList
- then the elements will be of type Point
:
static class Program
{
public static void Main(string[] args)
{
List<Point> AL = new List<Point>();
Random Rnd = new Random();
for (int i = 1; i <= 10; i++)
{
Point p = new Point(Rnd.Next(50), Rnd.Next(50));
AL.Add(p);
}
PrintValues(AL);
}
public static void PrintValues(IEnumerable<Point> myList)
{
foreach (var p in myList)
{
Console.WriteLine("X={0}, Y={1}", p.x, p.x);
}
}
}
As a final note, you might want to consider using the System.Drawing.Point
or System.Windows.Point
struct rather than rolling your own Point
class.