Как разветвлять код на основе типа данных класса - PullRequest
0 голосов
/ 28 февраля 2020

Я пытаюсь реализовать некоторые более сложные структуры данных в c#, работая без библиотек, кроме System. В настоящее время я работаю над графиками.

Я уже создал 3 класса для представления узлов, направленных ребер и неориентированных ребер. Каждый из них может иметь свой тип данных, например node<string> будет узлом с информацией, хранящейся в виде строки, а directedEdge<string> будет связывать узлы, в которых хранятся строки.

Мой класс графа объявлен как Graph<dataType, edgeType> ( на данный момент я предполагаю, что все ребра в одном графе одного типа), и я хотел бы выполнить ветвление внутри этого класса в зависимости от того, используется ли направленное или неориентированное ребро. Приведенный ниже код не работает, но объясняет функциональность, которую я хотел бы достичь.

if (edgeType == directedEdge<dataType>)
{

}
else if (edgeType == undirectedEdge<dataType>)
{

}
else
{

}

Есть ли способ реализовать нечто подобное тому, что показано выше? Если да, то как?

Ответы [ 2 ]

4 голосов
/ 28 февраля 2020

Хорошо, вы можете использовать сопоставление с образцом:

switch (edge)
{
    case directedEdge<dataType> de:
        // Do whatever..
        break;
    case undirectedEdge<dataType> ue:
        // Do whatever..
        break;
    default:
        // Do whatever..
        break;
}

В приведенном выше примере edge - это фактический экземпляр, а не тип.

Но это может быть не лучшим дизайном для реализовать, потому что по мере того, как вы вводите новые типы ребер, вам нужно будет также обновить оператор switch.

Если вы делаете это в нескольких местах, эффекты усиливаются.

Лучше, следуя Принципы OOP будут определять поведение в самих типах ребер:

abstract class Edge
{
    abstract void DoSomething();
}

class directedEdge<T> : Edge
{
    override void DoSomething() { }
}

class undirectedEdge<T> : Edge
{
    override void DoSomething() { }
}

тогда в вашем методе это просто:

Edge edge = // Some specific edge type
edge.DoSomething();
0 голосов
/ 28 февраля 2020

Есть несколько способов сделать это, следуя эволюции C# по годам.

  • Проверка типа времени выполнения

        Edge<int> edge = GetEdge(1);
        if (edge.GetType() == typeof(DirectedEdge<int>))
        {
        }
        else if(edge.GetType() == typeof(UnidirectedEdge<int>))
        {
        }
    
  • Использовать приведение с ключевым словом as

        Edge<int> edge = GetEdge(1);
        DirectedEdge<int> directed_edge = edge as DirectedEdge<int>;
        if (directed_edge != null)
        {
            // Use directed_edge
        } else {
            UnidirectedEdge<int> uni_edge = edge as UnidirectedEdge<int>;
            if (uni_edge != null)
            {
                // Use uni_edge
            }
        }
    
  • Использовать сопоставление с шаблоном if заявления

        Edge<int> edge = GetEdge(1);
    
        if (edge is DirectedEdge<int> directed_edge)
        {
            // Use directed_edge
        }
        else if (edge is UnidirectedEdge<int> uni_edge)
        {
            // Use uni_edge
        }
    
  • Использовать сопоставление с шаблоном switch оператор

        Edge<int> edge = GetEdge(1);
        switch (edge)
        {
            case DirectedEdge<int> directed_edge:
                // Use directed_edge
            case UnidirectedEdge<int> uni_edge:
                // Use unit_edge
            default:
                throw new NotSupportedException();
        }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...