在另一个列表中使用字符串列表时出现问题
本文关键字:列表 字符串 问题 另一个 | 更新日期: 2023-09-27 18:21:34
基本上,我要做的是将一本书的文本文件加载到一个字符串数组中,然后将各个页面以及书中每个页面的其他属性分解为单独的页面。当我试图将一个新项目添加到页面列表中时,在我调用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
}
}
将整本书加载到一个数组中,然后将该数组分解并添加到单独的页面中,这可能是一种效率低下的方法,因为您实际上在内存中存储了两次书,并处理了两次,一次加载,一次解析页面。
很难判断接口还是抽象方法是最好的方法,但由于您是在具体类中加载页面,因此接口可能更简单。
以下是一个不完整的例子,说明如何在一次通行证中阅读和处理这本书:
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; }
}
你可以将其进一步分解,例如通过拥有BookReader类,或者创建接口IDailyReflections和IDailyPage,但除非你在其他地方需要它们,否则这可能不值得。
我还建议设置单元测试,以验证您的方法是否有效,边缘案例是否得到处理(例如,第一页|最后一页没有日期)。然后,您可能会发现,最好将流传递给LoadPages,而不是文件名,从而避免了书籍始终是文件的假设,并使单元测试更容易实现(内存流与磁盘上的文件),使书籍阅读更灵活(从文件加载、从web加载等)
祝你好运!
经过一些实验,我发现了代码无法正常工作的主要原因。我把pageText变成了一个字符串,以使事情变得更简单(现在它不再是列表中的列表)并消除潜在的问题。主要问题是在我试图将新页面添加到页面列表的行上。问题不一定是清单中的清单。我在给日刊打电话。Add(temp);这并不是在列表的末尾创建一个新的日画实例,而是简单地指向内存中temp的位置。当我调用temp.pageText.Clear()时,它也会有效地清除并使dailypages.pageText为null,因为它们都引用了同一个内存块。
因此,这个问题通过替换日画而被消除了。添加(temp)与dailypages。Add(new dailyPage),它保留特定于dailyPage类型的新内存块。如果我要将dailypages.pageText作为一个列表,我需要为每个为dailypages创建的新列表项添加dailypage[totalPages-1]pageText.Add(新字符串),以使我的列表在列表中工作。我会发布"修复"的代码,但由于我对C#还很陌生,我相信你们这些老手会发现许多新手错误:)我还远远没有完成这个代码,但我想我会发布我发现的解决方案来解决我之前的问题。我从帖子中得到了一些有用的信息。
using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
namespace Books
{
abstract class Book // Class prototype for a book from a text file
{
public string bookTitle { get; set; } // the title
public string bookSubTitle { get; set; } // subtitle
public string bookAuthor { get; set; } // author
protected string[] bookText { get; set; } // book's text
protected int totalPages { get; set; } // Total number of pages
public Boolean loadError = false; // file not found marker
abstract internal void loadPages(); // seperates pages
// Generic class constructor
public Book(string filename)
{
if (File.Exists(filename)) // does text file book exist?
bookText = File.ReadAllLines(filename); //load bookText
else
{
loadError = true;// File was not found
ErrorMessage("File '"" + filename + "'" is missing.
'nClosing program.");
}
}
// Displays an error message
private static void ErrorMessage(string str)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(str);
Console.ResetColor();
}
// Prototype class for a page
protected abstract class Page
{
internal int pageNum { get; set; }
internal string pageText { get; set;}
}
}
// Class used specifically for the "Daily Reflections" book
class DailyReflections : Book
{
List<dailyPage> dailypages = new List<dailyPage>();
private DateTime today = DateTime.Now;
// Organizes pages from bookText[] into dailypages list
internal void loadPages()
{
DateTime date = new DateTime();
DateTime date2 = new DateTime();
string temptitle;
StringBuilder str = new StringBuilder();
for (int bookline = 0; bookline < bookText.LongLength;
bookline++)
{
if (DateTime.TryParse(bookText[bookline], out date))
{
bookline++;
temptitle = bookText[bookline].Trim();
while (!DateTime.TryParse(bookText[bookline], out
date2))
{
str.AppendLine(bookText[bookline]);
if (++bookline >= bookText.LongLength) break;
}
bookline--;
dailypages.Add(new dailyPage());
dailypages[totalPages].pageDate = date;
dailypages[totalPages].pageText = str.ToString();
dailypages[totalPages].pageNum = totalPages + 1;
dailypages[totalPages].pageTitle = temptitle;
str.Clear();
totalPages++;
}
}
}
// Class constructor unique to DailyReflections
public DailyReflections() : base("Daily Reflections.txt")
{
this.bookTitle = "Daily Reflections";
this.bookSubTitle = "";
this.bookAuthor = "";
loadPages();
}
// Display all lines of bookText
public void printText()
{
foreach (dailyPage txt in dailypages)
{
Console.WriteLine(txt);
}
}
// Page[] unique to DailyReflections
protected class dailyPage : Page
{
internal DateTime pageDate { get; set; }
internal string pageTitle { get; set; }
}
}
}