【问题标题】:Array with instances of different classes?具有不同类实例的数组?
【发布时间】:2015-03-14 17:52:36
【问题描述】:

我想知道是否有一种方法可以访问我在下面的代码中拥有的对象中的不同方法?

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication8
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            _test[0] = new TallGuy() {Height = 74, Name = "Teddy Long"};
            _test[1] = new TallGuy() {Height = 64, Name = "Teddy Shorter"};
            _test[2] = new TallGuy() {Height = 54, Name = "Teddy Shortest"};
        }

        private readonly object[] _test = new object[3];

        private void button1_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < _test.Length; i++)
            {
                //_test[i].        I can't call any methods here...
            }
        }
    }
}

我使用 Object 类型而不是一个类的数组背后的原因是因为我想在数组中存储不同类型的对象。在我的测试中途,虽然我注意到我无法访问我已经存储在数组中的对象的方法,因此为什么那里只有一种类型的对象。

【问题讨论】:

  • 确实,我打算添加不同的类型,但偶然发现了这个问题。决定在我继续之前先尝试解决它。​​
  • 您需要将对象转换为适当的类型才能访问其方法

标签: c# arrays object


【解决方案1】:

您可以通过检查类型并转换它们来访问方法:

var obj = _test[i] as TallGuy;
if (obj != null) Console.WriteLine("Height: {0}", obj.Height);

你也可以使用反射。

但是对象的类型是相关的吗?也许您应该考虑创建一个通用接口或超类并定义该类型的对象数组。

【讨论】:

  • 感谢您的回答。这是我决定看一看的 Head First C# 书中的一个“脑力”问题。问题如下“如果你有一些其他类不继承自 Worker 但确实实现了 InectarCollector 接口,那么它也可以完成这项工作!但由于它不继承自 Worker,你无法将它与其他蜜蜂一起放入数组中。你能想出一种方法来解决这个问题并创建一个包含蜜蜂和这个新类的数组吗?"
  • 这本书似乎正合我意:P 无论如何。这叫做多态性
【解决方案2】:

您只处理数组中的TallGuy 对象,因此您可以使用:

TallGuy[] _test = new TallGuy[3];

这将使您能够访问TallGuy 属性。

如果您还处理其他对象类型,例如SmallGuy,那么最好使用对象层次结构,然后使用强类型列表,而不是使用object

例如:

public abstract class Guy 
{
     abstract public int Height { get; set; }
}

public class TallGuy : Guy 
{
    public override int Height 
    {
        get { return 100; }
        set { } 
    }
}

public class ShortGuy : Guy 
{
    public override int Height 
    {
        get { return 10; }
        set { }
    } 
}

有了这个结构,你可以有一个List&lt;Guy&gt;,然后让Contravariance/Covariance接管。

List<Guy> people = new List<Guy>();
people.Add(new TallGuy());
people.Add(new ShortGuy());

另一种方法是将对象转换为 foreach 中的类型

 var tallGuy = _test[i] as TallGuy;

然后通过检查是否为空来检查转换是否成功:

if (tallGuy != null) {

}

(但是您不会有一个强类型列表,并且可能会因将对象装箱然后回滚而遇到性能问题。

【讨论】:

    猜你喜欢
    • 2021-07-18
    • 2014-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多