#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:
Здесь вам не нужен универсальный тип. Используя абстрактный базовый класс, вы можете решить две проблемы.
- Вы можете использовать базовый тип вместо универсального типа и получить доступ ко всем общедоступным членам этого базового класса.
- Вы можете добавить абстрактный метод в базовый класс, реализованный в двух производных классах, что сделает инструкцию 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. Иногда вы просто не видите ответа, пока он прямо перед вами! Большое спасибо за это предложение. Сейчас это работает блестяще.