打印 ArrayList 的值而不是类名

Print values of ArrayList instead of classname

我想为 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);
        }
    }

控制台输出:

Point 
Point 
Point 
Point 
Point 
Point 
Point 
Point 
Point 
Point 

我的问题是,打印的是对象的类名,而不是对象的值。 我正在使用 .NET Framework v4.8

您没有使用泛型集合,这在此处更为理想。但是因为您不是,所以您正在使用 objects。对象的默认 ToString 实现将 return 对象的名称。您需要将对象转换回 Point 类型才能使用它。

这是将对象投射回一个点的一种方法

public static void PrintValues(IEnumerable myList)
{
    
    foreach (var point in myList.Cast<Point>())
        Console.WriteLine($"{obj.X} {obj.Y}");
}

(旁白:我建议您不要定义自己的 class 称为 Point。它很可能与 built-in class 冲突并引起混淆。你应该给你的 class 一个不同的名字。)

所以,当您执行 Console.WriteLine(object obj) 时会发生什么,在 Console.WriteLine() 中它最终会调用 object.ToString() 来确定要写入的字符串。

默认情况下,如果您不编写自己的 ToString() 实现,它将 return class 的名称 - 这就是您看到 [=14] 的原因=] 在输出中。

由于您正在编写自己的 Point class,因此您可以将其 ToString() 覆盖为 return 格式化字符串。这是最好的解决方案。

假设您的 Point class 有 X 和 Y 值,您可以通过将以下内容添加到 class:

public override string ToString()
{
    return $"X={x}, Y={y}";
}

如果您不想这样做(或者假设它是您无法更改的 third-party class),则必须在将字符串传递给Console.WriteLine().

不幸的是,因为您使用的是 ArrayList,您最终只会得到一个 object - 所以为了格式化它,您需要将其转换为正确的类型才能获得它的 X 和 Y 值:

foreach (Object obj in myList)
{
    Point p = (Point)obj;
    Console.WriteLine("X={0}, Y={1}", p.x, p.y);
}

或者,如果您将循环变量声明为正确的类型,您可以利用 foreachIEnumerable 进行强制转换这一事实:

foreach (Point p in myList)
{
    Console.WriteLine("X={0}, Y={1}", p.x, p.x);
}

但是,使用 List<Point> 而不是 ArrayList 更好 - 这样元素的类型将是 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);
        }
    }
}

最后一点,您可能要考虑使用 System.Drawing.PointSystem.Windows.Point 结构,而不是滚动自己的 Point class.