在另一个列表中使用字符串列表的问题

时间:2015-11-12 09:31:04

标签: c# list class

基本上我要做的是将书本文本文件加载到字符串数组中,然后将各个页面拆分为单独的页面以及书中每个页面的其他属性。当我尝试将新项添加到页面列表中时,在调用temp.pageText.Clear()之后,它不会保留dailypages.pageText值。我是C#和面向对象编程的新手,所以我可能在这里做了不止一件事:)

abstract class Book
{
  abstract internal void loadPages();
  protected string[] bookText { get; set; }  // Load entire book text into
  /// Other generic book properties

  public Book(string filename)  // Load the book
  {
    bookText = File.ReadAllLines(filename);
  }

  protected abstract class Page  // Generic page properties
  {
    internal int pageNum { get; set; }
    internal List<string> pageText{ get; set; }  // Single page from the book

    public Page()    // Init list of strings
    {
      pageText = new List<string>();
    }
  }
}

class DailyReflections : Book
{
  List<dailyPage> dailypages = new List<dailyPage>();  // Init list of Pages

  override internal void loadPages()  // Split dailypages from bookText
  {
    DateTime date = new DateTime();
    DateTime date2 = new DateTime();
    dailyPage temp = new dailyPage();

    for (int bookline = 0; bookline < bookText.LongLength; bookline++)
    {
      if (DateTime.TryParse(this.bookText[bookline], out date))
      {
        bookline++;
        while (!DateTime.TryParse(bookText[bookline], out date2))
        {
          temp.pageText.Add(bookText[bookline]);
          if (++bookline >= bookText.LongLength) break;
        }
        bookline--;
      }
      temp.dailyDate = date;
      dailypages.Add(temp);
      temp.pageText.Clear();
      this.totalPages++;
    }
  Console.WriteLine(dailypages[0].pageText[0]); 
//    ^^^ This line I get an out of range error, this should be line 1 of the 
//    first page. Same error with any index used. If I take out the line
//    temp.pageText.Clear(); (used to clear the text to fill it with the next
//    page, maybe I am using it wrong). Without the .Clear() dailypages[0]
//    contains page 1, [1] contains page 1 and page 2, [2] pages 1,2,3 since.
//    it continues adding to the end of temp.pageText without clearing the 
//    last page.
  }

  protected class dailyPage : Page  // Page with values unique to the book
  {
    internal DateTime dailyDate { get; set: }  // Date on the page
    internal string pageTitle { get; set; }  // Title of the page
  }
}

2 个答案:

答案 0 :(得分:0)

Loading the entire book into an array, and then breaking that array up and adding to separate pages might be an inefficient way to go about it, since you're effectively storing the book twice in memory, and processing it twice, once to load, and once to parse pages.

It's a bit hard to tell if an interface or abstract approach is the best way to go, but since you're loading the pages in your concrete class, an interface might be simpler.

Here's an incomplete example of how you could read and process the book in a single pass:

public interface IBook
{
    // List might be too specific, IEnumerable might work fine
    List<IPage> Pages { get; set; }

    // ctor loading is ok, but harder to unit test and define via interface
    void LoadPages(string fileName); 
}

public interface IPage
{
    int Number { get; set; }
    string Text { get; set; }
}

public class DailyReflections : IBook
{
    List<IPage> Pages { get; set; }

    public void LoadPages(string fileName)
    {            
        // Read one line at time, perhaps by appending line to StringBuilder
        // Attempt to parse date on this line, then when your date parses, 
        // create new DailyPage from StringBuilder text and date, then add to Pages.
        // Then clear your StringBuilder and continue until all lines are read.
        // e.g. https://msdn.microsoft.com/en-us/library/system.io.streamreader.readline(v=vs.110).aspx
    }
}

public class DailyPage : IPage
{
    public int Number { get; set; }
    public string Text { get; set; }
    public DateTime Date { get; set; }
}

You could break this up further, for example by having a BookReader class, or creating interfaces IDailyReflections and IDailyPage, but unless you're going to need them elsewhere, it may not be worthwhile.

I'd also advise setting up unit tests to verify that your approach is working, and edge cases are dealt with (e.g. no date on first|last page). You might then discover it's better to pass a stream to LoadPages rather than a filename, thereby avoiding the assumption that the book is always a file, and making both your unit testing simpler to implement (in-memory stream vs file on disk), and your book reading more flexible (load from file, load from web, etc.).

Good luck!

答案 1 :(得分:0)

经过一些实验后,我发现了代码无法正常工作的主要原因。我将pageText转换为字符串以使事情更简单(它现在不再是列表中的列表)并消除潜在的问题。主要问题是我试图将新页面添加到页面列表的行。问题不一定是列表中的列表。我在调用dailypages.Add(temp);它没有在列表的末尾创建dailypages的新实例,而是简单地指向内存中temp的位置。当我调用temp.pageText.Clear()时,它也会有效地清除并生成null dailypages.pageText,因为它们都指向相同的内存块。

所以通过替换dailypages来消除这个问题。添加(temp)和dailypages.Add(new dailyPage),它保留了特定于dailyPage类型的新内存块。如果我要将dailypages.pageText保存为列表,我需要为dailypages创建的每个新列表项的dailypages [totalPages-1] .pageText.Add(新字符串),以使我的列表在列表中工作。我将发布“已修​​复”的代码,但由于我仍然是C#的新手,我相信你的退伍军人会发现许多新手错误:)我还没有完成这个代码,但我想我会发布我找到的解决方案我之前的问题。我从帖子中得到了一些有用的信息。

RUNNING_CONTAINERS=$(docker ps -a | grep ${IMAGE_NAME})