2015-05-18 3 views
-4

У меня есть вопрос о следующих двух конструкторов, которые одновременно являются частью Graph class Я пытаюсь порта через от Java:В C#, как я могу правильно перегрузить этот конструктор?

public Graph(int V) 
    { 
     this.m_V = V; this.m_E = 0; 
     adj = new Bag<int>[V]; 
     for (int v = 0; v < V; v++) 
      adj[v] = new Bag<int>(); 
    } 
    public Graph(TextReader inpt) : this(int.Parse (inpt.ReadLine())) 
    { 
     //int V = int.Parse (inpt.ReadLine()); 
     int E = int.Parse (inpt.ReadLine()); 
     //this(V); 
     for (int i = 0; i < E; i++) 
     { // Add an edge. 
      string[] inputs = inpt.ReadLine().Split (' '); 
      int v = int.Parse (inputs [0]); 
      int w = int.Parse (inputs [1]); 
      addEdge(v, w); 
     } 
    } 

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

Мой вопрос: что бы произошло, если бы V было вторым целым во входной последовательности (что означает, что мне пришлось бы дважды вызвать ReadLine()), и как бы выглядел похожий вызов цепочки конструктора в этом случае? И будет ли цепочка возможна даже без экспорта какой-либо логики в другой метод?

Edit Главный вопрос, и я думаю, я понимая, как это обсуждение продолжается, о гибкости конструктора в C# по сравнению с Java один. Например, я могу позвонить this(v) в java после того, как дважды позвоню ReadLine(), но как я могу добиться того же в C#?

+5

Вызов 'ReadLine' в конструкторе кажется ДЕЙСТВИТЕЛЬНО плохой идеей. –

+0

Согласен, но мне просто интересно, как я могу перевести между прокомментированным javaish кодом на C#. – rivanov

+5

'без экспорта некоторой логики в другой метод? Похоже, вы уже знаете точно, как это сделать. Извлеките его в метод. Бам, сделано. Или вы просто не можете быть жестокими и вообще не делать этого, как это было предложено. Лично я предлагаю статический заводский метод над конструктором для этого случая. – Servy

ответ

1

Внимание, код, который вы собираетесь просмотреть, не подходит для большинства зрителей.

Показанный здесь код предназначен исключительно для развлекательных целей и не должен использоваться в фактическом производственном коде.

Если у вас есть действительно хотите запустить произвольный код в строке перед вызовом другого конструктора, вы можете сделать это, вставив анонимный метод, который будет немедленно выполнен.

public class EvilGraph 
{ 
    public EvilGraph(int V) 
    { 
     //... 
    } 
    public EvilGraph(TextReader inpt) 
     : this(new Func<int>(() => 
     { 
      inpt.ReadLine(); 
      return int.Parse(inpt.ReadLine()); 
     })()) 
    { 
     //... 
    } 
} 

Насколько, как вы должны фактически решить эту проблему; это не должно быть конструктором. Это должен быть статический заводский метод, который может выполнить некоторую работу, построить Graph с использованием фактического конструктора графа, а затем выполнить некоторую дополнительную обработку на этом Graph, прежде чем возвращать его вызывающему. Это устраняет все проблемы, связанные с тем, когда во время этого процесса строительства должны выполняться другие вызовы конструктора.

+0

Спасибо, что свели свет к моему наивному мозгу!У меня бы никогда не было статической фабрики, потому что я действительно не очень хорошо разбираюсь в шаблонах дизайна (возможно, я должен был упомянуть об этом в сообщении) – rivanov

+0

@rivanov Знаете ли вы, какое имя может быть названо конкретным шаблоном isn ' Здесь очень важно. Все, что вам нужно, это статический метод; ему даже не нужно быть в другом классе (на самом деле, я бы сказал, что он даже не принадлежит другому классу). Хотя есть имена для этого шаблона, вы не * действительно * должны знать или заботиться о любом из них, просто используйте свой статический метод для создания объекта. – Servy

 Смежные вопросы

  • Нет связанных вопросов^_^