Обнаружение вложенного типа универсального

#c# #generics #pattern-matching

Вопрос:

Я работаю над проектом, в котором необходимо определить тип объекта, взять информацию из этого типа и перенести ее в структуру, которая вписывается в нашу базу данных.

Для этого я использую сопоставление шаблона с оператором case, который отлично работает.

Единственное, на чем я застрял, так это на том, что некоторые типы также имеют вложенные типы. Информация в этих вложенных типах-это та информация, которая мне нужна.

Взгляните на приведенный ниже код:

     public class CallAnswered
    {
        public string Caller { get; set; }
        public MetaDataInformation MetaData{ get; set; }
    }

    public class CallAbandoned
    {
        public string ReasonForAbandonment{ get; set; }
        public MetaDataInformation MetaData { get; set; }
    }

    public class MetaDataInformation 
    {
        public DateTime ReceivedAt { get; set; }
        public DateTime AnsweredAt { get; set; }
    }

    public void DetermineType<T>(T callEvent)
    {
        switch (callEvent)
        {
            case CallAnswered callAnswered:
            case CallAbandoned callAbandoned:

            // Somehow, I need to access the "MetaData" property as a type
            break;
        }
    }
 

Как показано в приведенном выше коде, я могу определить родительский тип и назначить ему переменную. Но я понятия не имею, как получить вложенный MetaDataInformation тип.

У кого-нибудь есть идеи, как это можно решить?

Комментарии:

1. Имеют наследование CallAnswered и CallAbandoned от одного и того же класса или интерфейса, требующего метаданной.

2. Однако я бы рекомендовал переосмыслить вашу архитектуру здесь. Каждый раз, когда вы пытаетесь выяснить, что это за тип, вы почти всегда идете по неверному пути.

Ответ №1:

Здесь вам не нужен универсальный тип. Используя абстрактный базовый класс, вы можете решить две проблемы.

  1. Вы можете использовать базовый тип вместо универсального типа и получить доступ ко всем общедоступным членам этого базового класса.
  2. Вы можете добавить абстрактный метод в базовый класс, реализованный в двух производных классах, что сделает инструкцию switch устаревшей.
 public abstract class Call
{
    public MetaDataInformation MetaData { get; set; }
    public abstract void Process();
}

public class CallAnswered : Call
{
    public string Caller { get; set; }

    public override void Process()
    {
        // TODO: Do Answer things. You can access MetaData here.
    }
}

public class CallAbandoned : Call
{
    public string ReasonForAbandonment{ get; set; }

    public override void Process()
    {
        // TODO: Do Abandonment things. You can access MetaData here.
    }
}
 

где-нибудь в другом месте

 public void ProcessCalls(Call callEvent)
{
    // Replaces switch statement and does the right thing for both types of calls:
    callEvent.Process();
}
 

Это называется полиморфным поведением.

Смотрите также:

Комментарии:

1. Иногда вы просто не видите ответа, пока он прямо перед вами! Большое спасибо за это предложение. Сейчас это работает блестяще.