Расширение функциональности полей базового класса - PullRequest
2 голосов
/ 04 июня 2011

У меня есть следующий код, который представляет ребра и узлы графа (упрощенно для вопроса):

public class Node
{
}

public class Edge
{
    public Node Source { get; set; }
    public Node Target { get; set; }
}

Теперь я хочу расширить эти классы для описания топологии шахты:

public class MineNode : Node
{
    public double FanPressure { get; set; }
}

public class MineTunnel : Edge
{
    public double Length { get; set; }
    public double CrossSectionArea { get; set; }

    public MineTunnel()
    {
        Source = new MineNode();
        Target = new MineNode();
    }
}

проблема в том, что я хочу получить доступ к дополнительным данным, предоставляемым MineNode при использовании свойств Source и Target, но я могу получить доступ только к полям Node, поскольку они объявлены в базовом классе:

MineTunnel t = new MineTunnel();
Console.WriteLine(t.Source.FanPressure); //Error

Единственный способ получить доступ к FanPressure - привести Source к MineNode, но код станет таким уродливым.

Console.WriteLine(((MineNode)t.Source).FanPressure); //OK

Другой способ, возможно, заключается в использовании каких-либо обобщений в объявлении базового класса.Но я не уверен, что это хорошая практика в моей ситуации.

Итак, как я могу решить эту проблему - расширить функциональность полей базового класса?

Спасибо.

Ответы [ 2 ]

6 голосов
/ 04 июня 2011

Вы можете определить тип Edge как общий с ограничениями:

public class Edge<TNode> where TNode: Node
{
  public TNode Source { get; set; }
  public TNode Target { get; set; }
}

С помощью которого вы можете переопределить ваш MineTunnel тип как:

public class MineTunnel : Edge<MineNode>
{
  // Stuff
}
1 голос
/ 04 июня 2011

Я думаю, что дженерики - это путь сюда ...

Попробуйте это:

public class Node
{

}

public class Edge<S, T>
    where S : Node
    where T : Node
{
    public S Source { get; set; }
    public T Target { get; set; }
}

Затем вы можете расширить классы Node и Edge с помощью:

public class MineNode : Node
{
    public double FanPressure { get; set; }
}

public class MineTunnel : Edge<MineNode, MineNode>
{
    public double Length { get; set; }
    public double CrossSectionArea { get; set; }

    public MineTunnel()
    {
        Source = new MineNode();
        Target = new MineNode();
    }
}

Пожалуйста, поправьте меня, если это не так или не работает ...:)

MineTunnel t = new MineTunnel();
Console.WriteLine(t.Source.FanPressure); // Now this works without errors ;)
...