2015-03-14 3 views
2

Мне интересно, есть ли способ получить доступ к различным методам в объектах, которые у меня есть в коде ниже?Массив с экземплярами разных классов?

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

Причина позади меня, используя тип объекта, а не массив одного класса, потому что я хочу, чтобы хранить различные типы объектов в массиве. В середине моего тестирования, хотя я заметил, что мне не удалось получить доступ к методам объектов, которые я уже хранил в массиве, следовательно, существует только один тип объектов.

+0

Действительно, я планировал добавлять разные типы, но наткнулся на эту проблему. Решил попробовать его решить, прежде чем продолжить. – Lithicas

+0

Чтобы получить доступ к его методам, необходимо применить объект к соответствующему типу – DarkBee

ответ

4

Вы можете получить доступ к методам путем проверки типов и литья их:

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

Вы также можете использовать отражение.

Однако существуют ли типы связанных объектов? Возможно, вам стоит подумать о создании общего интерфейса супер класса и определить массив объектов этого типа.

+0

Спасибо за ответ. Это был вопрос «Мозговой силы» в книге Head First C#, на которой я решил взглянуть. Вопрос был следующий: «Если у вас есть какой-то другой класс, который не наследуется от Worker, но реализует интерфейс INectarCollector, то он тоже сможет выполнять эту работу! Но поскольку он не наследуется от Worker, вы не может попасть в массив с другими пчелами. Можете ли вы подумать о том, как обойти проблему и создать массив с пчелами и этим новым классом? " – Lithicas

+0

Это похоже на мою аллею в этой книге: P В любом случае. Это называется полиморфизмом – DarkBee

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<Guy>, а затем пусть Contravariance/Covariance взять на себя.

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

Альтернативный подход является приведение объекта к типу в Еогеасп

var tallGuy = _test[i] as TallGuy; 

А затем проверить, если бросок успешно был проверкой, если она равна нулю:

if (tallGuy != null) { 

} 

(Но у вас не было бы строго типизированного списка, и он мог бы поразить проблемы производительности при боксинге объектов, а затем отбросить назад).

Смежные вопросы