Доступ к дочерним свойствам из словаря, в котором хранится тип родительского класса

1

У меня есть ситуация, когда я хотел бы создать словарь, который может содержать родительский и дочерний типы. Я хотел бы хранить разные типы детей и иметь возможность вызывать их данные.

Проблема, с которой я столкнулась, заключается в том, что при вытаскивании объектов из словаря они рассматриваются как их родительский тип, поскольку тип словаря задан как родительский объект. Единственный способ, которым я решил получить доступ к их дополнительным свойствам, - это создать экземпляр нового объекта с помощью var (см. Ниже).

Любая помощь будет очень оценена. Кроме того, если мой лингво/терминология неверна, пожалуйста, не стесняйтесь исправлять меня, поскольку я пытаюсь учиться. Благодарю!

Обновление: я немного обновил свой код, чтобы попытаться точно передать то, что я пытаюсь сделать. (добавлен цикл foreach).

        public class parent
        {
            public string name;     
        }

        public class child : parent 
        {
           public int age;      
        }

        public class library
        {               
        }

        public class Program
        {
           public static void Main(string[] args)
           {                
              Dictionary<int, parent> dictionary = new Dictionary<int, parent>();
              child child1 = new child();
              child child2 = new child();

              child1.age = 5;
              child2.age = 10;

              dictionary.Add(1,child1);
              dictionary.Add(2,child2);    


     foreach(KeyValuePair<int, parent> d in dictionary)  
    {

    Console.WriteLine(d.age);

    }                  


          }
}
  • 0
    Даже если ваш код показывает задействованные объекты и типы, он на самом деле не показывает проблему, с которой вы столкнулись. Это правильный этикет, чтобы показать минимальный объем кода, который демонстрирует вашу проблему.
Теги:

2 ответа

1

Здесь другой способ доступа только к child членам словаря:

Dictionary<int, parent> dictionary = new Dictionary<int, parent>();
child child1 = new child();
child child2 = new child();

child1.age = 5;
child2.age = 10;

dictionary.Add(1,child1);
dictionary.Add(2,child2);
dictionary.Add(45, new parent());

foreach(var c in dictionary.Select(x => x.Value).OfType<child>())
{
    Console.WriteLine(c.age);
}

Это дает мне всего 5 и 10 и игнорирует parent объект, который я помещаю в словарь.

  • 0
    Спасибо! Это работает также. :)
1

Возможно, ваш дизайн ошибочен, если вы это делаете, но у вас уже есть это правильно.

var child1a = child1 as child;

Не создавать новый объект. Он просто понижает тип child элемента. Downcasting - это запах кода, поэтому подумайте о том, чтобы переработать свой дизайн там, где это не нужно.

Кроме того, так as будет возвращено значение null если сбой выполняется, вы должны его проверить:

var child1a = child1 as child;

if (child1a != null)
  Console.WriteLine(child1a.age);

Наконец, вы никогда не использовали словарь в своем коде, скорее всего, захотите сделать:

var child1a = dictionary[1] as child;

if (child1a != null)
  Console.WriteLine(child1a.age);

Для вашего обновления этот цикл никогда не будет работать (и не должен). Не все объекты в вашей коллекции гарантированно обладают свойством "возраст".

Что касается вашей циклы, вы можете сделать это:

foreach (child item in dictionary.Values)
{
    ...
}

или:

foreach (KeyValuePair<int, parent> kvp in dictionary)
{ 
   if (kvp.Value is child)
   {
       child item = (child)kvp.Value;
       ...
   }
}

Который вытащит child элементы из вашей коллекции ценностей и позволит вам использовать их как таковые. Если это все, что вы делаете, Dictionary здесь слишком переполнен.

  • 0
    Ты прав. Я на самом деле хотел поставить «var child1a = new child1 как child»; когда я имел в виду создание нового объекта. Тем не менее, я все еще ищу решение для получения объекта из словаря в качестве дочернего объекта. Я обновлю свой код, но я хочу извлечь каждый элемент из словаря и получить доступ к дочерним свойствам. Спасибо.
  • 0
    @parrotsnest Я обновлю свой ответ, чтобы включить это, но вы просто не можете этого сделать. Если вы сохранили его в качестве базового класса, он выйдет таким образом, конец истории. Вы должны разыграть, чтобы получить производные свойства. Тот факт, что это необходимо, означает, что вы, вероятно, настроили свой дизайн неправильно. Исправление вашего дизайна является реальным решением.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню