-1

可能重复:
为什么我必须在默认为 0 时为 C# 中的 int 赋值?

我刚刚开始通过编写一个名为 Journal 的人为应用程序来学习 C#。在解析日志文件的函数中,我声明了变量DateTime currentEntryDate. 在我到达定义新条目的行之前,它不会获得值。第二到达入口行时,该变量将用于JournalEntry为前一个入口创建类的实例。

问题是使用变量的代码无法编译:

使用未分配的局部变量“currentEntryDate”

这对我来说毫无意义。为了让编译器满意,我真的必须给我的变量一个浪费的初始值吗?当然我误解了一些东西,或者我的代码某处有错误。

Pastebin上的代码:Journal.cs。我已经强调了相关的行。

编码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;

namespace Journal
{
    class Journal
    {
        public List<JournalEntry> Entries;

        private static readonly string EntryLineRegex =
            @"-- Entry: (?<title>.*) \((?<year>\d{4})-(?<month>\d{2})" +
            @"-(?<day>\d{2})\)";

        public static Journal FromFile(string filePath)
        {
            Journal returnValue = new Journal();

            StreamReader fileReader = new StreamReader(filePath);

            // Prepare variables for parsing the journal file.
            bool hitFirstEntry = false;
            DateTime currentEntryDate;
            string currentEntryTitle;
            StringBuilder currentEntryText = new StringBuilder();

            // Prepare a regular expression for the entry lines.
            Regex entryLineRegex = new Regex(EntryLineRegex);

            while (!fileReader.EndOfStream)
            {
                string line = fileReader.ReadLine();

                if (line.StartsWith("--"))
                {
                    // Is this the first entry encountered? If so, don't try to
                    // process the previous entry.
                    if (!hitFirstEntry)
                    {
                        hitFirstEntry = true;
                    }
                    else
                    {
                        // Create a JournalEntry with the current entry, then
                        // reset for the next entry.
                        returnValue.Entries.Add(
                            new JournalEntry(
                                currentEntryText.ToString(), currentEntryDate
                            )
                        );

                        currentEntryDate = new DateTime();
                        currentEntryText.Clear();
                    }

                    // Extract the new entry title and date from this line and
                    // save them.
                    Match entryMatch = entryLineRegex.Match(line);
                    GroupCollection matches = entryMatch.Groups;

                    currentEntryDate = new DateTime(
                        Convert.ToInt16(matches["year"].Value),
                        Convert.ToInt16(matches["month"].Value),
                        Convert.ToInt16(matches["day"].Value)
                    );

                    currentEntryTitle = matches["title"].Value;
                }
                else
                {
                    currentEntryText.Append(line);
                }
            }

            return returnValue;
        }
    }

    class JournalEntry
    {
        public string Text;
        public DateTime EntryDate;

        public JournalEntry(string text, DateTime entryDate)
        {
            this.Text = text;
            this.EntryDate = entryDate;
        }
    }
}
4

5 回答 5

2

我认为这里的问题是编译器不够聪明,无法掌握您读取输入的方式,并且存在变量不会被初始化的执行路径,即如果它通过第else一个,在if. 为避免这种情况,您可能需要在定义时进行初始化。

于 2013-01-20T08:45:28.567 回答
2

像这样重组你的循环怎么样?这将确保currentEntryDate在您使用它之前具有值:

string line = fileReader.ReadLine();
while (line != null)
{
    // Extract the new entry title and date from this line and
    // save them.
    Match entryMatch = entryLineRegex.Match(line);
    GroupCollection matches = entryMatch.Groups;

    currentEntryDate = new DateTime(
        Convert.ToInt16(matches["year"].Value),
        Convert.ToInt16(matches["month"].Value),
        Convert.ToInt16(matches["day"].Value)
    );

    currentEntryTitle = matches["title"].Value;

    while ((line = fileReader.ReadLine()) != null && !line.StartsWith("--"))
    {
        currentEntryText.Append(line);
    }

    // Create a JournalEntry with the current entry, then
    // reset for the next entry.
    returnValue.Entries.Add(
        new JournalEntry(
            currentEntryText.ToString(), currentEntryDate
        )
    );

    currentEntryText.Clear();
}
于 2013-01-20T08:59:38.150 回答
2

在这种情况下,编译器没有意识到 和 之间的“依赖hitFirstEntrycurrentEntryDate

即使您可以“证明”无论何时hitFirstEntry更改为true,然后将currentEntryDate很快分配 ,并且直到(最早)在循环的下一次迭代中才第一次读取,编译器不是那个复杂。也许你可以重新编写你的代码。currentEntryDate

编辑:这是您的代码的“最小”版本:

        bool isFirstTime = true;
        DateTime localVarToBeAssigned;

        while (true)
        {
            if (isFirstTime)
            {
                isFirstTime = false;
            }
            else
            {
                // this reads the variable
                Console.WriteLine(localVarToBeAssigned);
            }

            // this assigns the variable
            localVarToBeAssigned = DateTime.Now;
        }
于 2013-01-20T08:59:54.487 回答
1

如果你真的,真的不想实例化它:

DateTime? currentEntryDate = null

问号使 DateTime 可以为空,它通常不是。

于 2013-01-20T08:56:24.713 回答
-2

您声明局部变量,此变量没有默认值,并从堆栈中获取它们的内存,您应该在使用它们之前初始化局部变量,并与此代码的更改行一起使用:

currentEntryDate = new DateTime();

你的代码行得通,

于 2013-01-20T08:56:22.410 回答