2013-05-09 6 views
0

Я действительно новичок в C#. У меня есть несколько экземпляров компьютеров, и у каждого из них есть имя, остановка, запуск и перезапуск команд, связанных с каждым из них. Я хочу прочитать информацию из файла.Массив массивов с несколькими объектами

Так что я хочу в итоге instancelist[0].Instance_name=Enterprise1 и instancelist[0][email protected]_stop и instancelist[1].Instance_name=Enterprise5 и так далее. Я могу понять, как это сделать.

public class Instance 
{ 
    public string Instance_name; 
    public string Instance_stop; 

    public string Instance_restart; 
    public string Instance_backup; 
} 

public static void Main(string[] args) 
{ 
    int num_instances=0; 

    /** CAN'T figure out the declaration. I'm currently thinking array of array? */ 

    System.IO.StreamReader file = new System.IO.StreamReader(@"C......"); 

    while(true) 
    { 
     instancelist[num_instance].Instance_name=file.ReadLine(); 
     instancelist[num_instance].Instance_stop=file.ReadLine(); 
     // and so on....... 
     num_instance++; 
    } 
} 
+0

Я думаю, вы говорите о «неровными» массивов: вот ссылка, которая объясняет использование: http://msdn.microsoft.com/en-us/library/2s05feca.aspx –

+2

Привет! Я потратил время на форматирование кода, но в будущем вы должны сделать свой код презентабельным, прежде чем публиковать свой вопрос. (Чтобы опубликовать много кода за один раз, используйте выбор «Образец кода», чтобы отложить все это на четыре пробела, что делает его форматированием как код) – Patashu

ответ

2

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

Вам также понадобится класс DTO. Так вот некоторый код (непроверенный):

// DTO Class 
public class Instance 
{ 
    public string Instance_Start { get; set; } 
    public string Instance_Stop { get; set; } 
} 

var instanceList = new List<Instance>; 
var file = new System.IO.StreamReader(myFile); 

while(!file.EndOfStream) 
{ 
    var instance = new Instance 
    { 
     Instance_Start = file.Readline(); 
     Instance_Stop = file.Readline(); 
    }; 

    instanceList.Add(instance); 
    num_instance++; 
} 

Обратите внимание, что вы можете получить доступ к элементам на instanceList по индексу, как в

instanceList[0].InstanceStart 
+0

Вы действительно не отвечаете на вопрос OP правильно ... список экземпляров а не набор строк, это набор объектов экземпляра. – guysherman

+0

@guysherman: Исправлено. –

0

Это звучит, как вы хотите, чтобы получить коллекцию этих Instance объектов, каждый из которых будет разбираться из набора смежных строк в файле.

Я бы рекомендовал что-то вроде этого:

// First: a static method to create an Instance object from a few 
// consecutive lines in a stream 
class Instance 
{ 
    public static Instance ReadFromStream(StreamReader reader) 
    { 
     var instance = new Instance(); 
     instance.InstanceName = reader.ReadLine(); 
     instance.InstanceStop = reader.ReadLine(); 
     // etc. 
     return instance; 
    } 
} 

// Then, elsewhere: use a List<T> (an expandable collection) 
// to store all the instances you create from reading the file. 
// Note that the 'using' statement automatically closes the file 
// for you when you're done. 
var instances = new List<Instance>(); 
using (var reader = new StreamReader(filePath)) 
{ 
    while (!reader.EndOfStream) 
    { 
     instances.Add(Instance.ReadFromStream(reader)); 
    } 
} 
0

Вы вопрос довольно расплывчатым, но вот моя попытка ответа.

Apparantly у вас есть класс с именем «Instance», я предложил бы создать список экземпляров класса «Instance»:

using System.Collections.Generic; // Add this to the rest of 'usings' 

public static void Main(string[], args) 
{ 
    // Create a new stream to read the file 
    StreamReader SReader = new StreamReader("C:\file.txt"); 

    // Create a list of 'Instance' class instances 
    List<Instance> AllInstances = new List<Instance>(); 

    // Keep reading until we've reached the end of the stream 
    while(SReader.Peek() > 0) 
    { 
     // Read the line 
     string CurrentLine = SReader.ReadLine(); // if you call this multiple times in this loop you proceed multiple lines in the file.. 

     // Create an new instance of the 'Instance' class 
     Instance CurrentInstance = new Instance(); 

     // Assign the 'Name' property 
     CurrentInstance.Name = CurrentLine; 

     // Add class instance to the list 
     AllInstances.Add(CurrentInstance); 
    } 

    // Close the stream 
    SReader.Close(); 
} 

В конце концов вы будете иметь список классов «Instance». Для получения дополнительной информации о списке:

http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx

А относительно StreamReader:

http://msdn.microsoft.com/en-us/library/system.io.streamreader.aspx

0

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

Вы могли бы сделать что-то вроде этого:

// Convention in C# is to use properties instead of fields for something like this 
// also, having the class name in the field name is redundant 
public class Instance 
{ 
    public string Name {get;set;} 
    public string Stop {get;set;} 

    public string Restart {get;set;} 
    public string Backup {get;set;} 
} 

public static void Main(string[] args) 
{ 
    List<Instance> items = new List<Instance>(); 

    // the using block will close the file handle 
    using (System.IO.StreamReader file = new System.IO.StreamReader(@"C......")) 
    { 
     while(true) 
     { 
      String name = file.ReadLine(), stop = file.ReadLine(), restart = file.ReadLine(), backup = file.ReadLine(); 
      if (name == null || stop == null || restart == null || backup == null) 
       break; // I didn't test it, but this should work for determining the end of the file 
      items.Add(new Instance(){ 
       Name = name, 
       Stop = stop, 
       Restart = restart, 
       Backup = backup 
      }); 
     } 
    } 
} 

Если вы должны быть в состоянии найти значения для конкретного имени, существует два подхода. Один из них - это циклическое сопоставление с именем Name и сохранение индекса List. Более идиоматических способ сделать это (хотя это не так просто для новой пришелец читать) является:

String nameToFind = "..."; 
String stop = items.Where(item => item.Name == nameToFind).FirstOrDefault().Stop; 

Обратите внимание, что FirstOrDefault вернется null, если такой элемент не найден, в этом случае .Stop разыменования будет бросить исключение.

С другой стороны, если вы действительно хотите, чтобы вся эта структура данных была проиндексирована по имени, List (или массив) может быть не лучшим способом. Другим решением может быть:

public class Instance2 
{ 
    public string Stop {get;set;} 
    public string Restart {get;set;} 
    public string Backup {get;set;} 
} 

Dictionary<String, Instance2> items = new Dictionary<String, Instance2>(); 

// ... 

items[name] = new Instance2(){Stop = stop, 
    Restart = restart, 
    Backup = backup}; 

со структурой данных, как это, глядя на имя является гораздо более эффективным (по сравнению с O(log(n))O(n)). Вы бы просто сделать:

String nameToFind = "..."; 
String stop = items[nameToFind].Stop; 
+0

Мне это нравится, но после его чтения в список мне нужно найти «Имя» и вернуть значение в «Стоп». Если Список не проиндексирован, как бы выполнить поиск по имени и вернуть строку в Stop. Может быть, я просто не понимаю концепцию List? Потому что это просто похоже на длинный список объектов без имени, остановки, перезагрузки и резервного копирования, связанных друг с другом. –

+0

Обновлено. Списки легко найти. – bmm6o

+0

Я не уверен, что вы имеете в виду, что они связаны друг с другом. Части связанных данных все живут в одном и том же объекте. Возможно, запустите его в отладчике, и вы увидите, как выглядит List или Dictionary. – bmm6o

0

У вас есть несколько вариантов, если вы знаете, количество экземпляров заранее, вы можете использовать массив, но в противном случае вы можете также использовать List<Instance>.

public static void main(string[] args) 
{ 
    List<Instance> instancelist = new List<Instance>(); 

    System.IO.StreamReader file = new System.IO.StreamReader(@"C......"); 
    while (! file.EndOfStream) // rather than while(true) which never stops 
    { 
      // Even if this were in an array, instancelist[i].Instance_name would be a null pointer exception, 
      // So we create the instance and then add it to the list 
      var instance = new Instance(); 
      instance.Instance_name = file.ReadLine(); 
      //... etc 

      instancelist.Add(instance); 
    } 
} 
Смежные вопросы