C# 我真的必须给所有变量一个初始值吗?

C# 我真的必须给所有变量一个初始值吗?,c#,C#,可能重复: 我刚刚开始学习C#,通过编写一个名为Journal的人工应用程序。在解析日志文件的函数中,我声明了变量DateTime currentEntryDate。在到达定义新条目的行之前,它不会得到值。第二次到达条目行时,该变量将用于为上一条条目创建classJournalEntry的实例 问题是使用变量的代码无法编译: 使用未分配的局部变量“currentEntryDate” 这对我来说毫无意义。我真的必须给我的变量一个浪费的初始值才能让编译器满意吗?肯定是我误解了什么,或者我的代码中有

可能重复:

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

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

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

这对我来说毫无意义。我真的必须给我的变量一个浪费的初始值才能让编译器满意吗?肯定是我误解了什么,或者我的代码中有个错误

Pastebin上的代码:。我已经突出显示了相关的行

守则:

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;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Text.RegularExpressions;
使用System.IO;
名称空间日志
{
班级日记
{
公开名单条目;
私有静态只读字符串EntryLineRegex=
@“--条目:(?.*)\(?\d{4})-(?\d{2})”+
@“-(?\d{2}\)”;
公共静态日志FromFile(字符串文件路径)
{
日记账返回值=新日记账();
StreamReader fileReader=新的StreamReader(文件路径);
//准备用于分析日志文件的变量。
bool-hitFirstEntry=false;
日期时间currentEntryDate;
字符串currentEntryTitle;
StringBuilder currentEntryText=新建StringBuilder();
//为输入行准备正则表达式。
正则表达式entryLineRegex=新正则表达式(entryLineRegex);
而(!fileReader.EndOfStream)
{
string line=fileReader.ReadLine();
if(第行开始,以“-”号填列)
{
//这是遇到的第一个条目吗?如果是,请不要尝试
//处理上一个条目。
如果(!hitFirstEntry)
{
hitFirstEntry=true;
}
其他的
{
//使用当前条目创建日志,然后
//为下一个条目重置。
returnValue.Entries.Add(
新期刊(
currentEntryText.ToString(),currentEntryDate
)
);
currentEntryDate=新的日期时间();
currentEntryText.Clear();
}
//从此行中提取新条目标题和日期,然后
//拯救他们。
Match entryMatch=entryLineRegex.Match(行);
GroupCollection matches=entryMatch.Groups;
currentEntryDate=新日期时间(
转换为16(匹配[“年”].值),
转换为16(匹配[“月”].值),
转换.ToInt16(匹配[“天”].Value)
);
currentEntryTitle=匹配[“title”]。值;
}
其他的
{
currentEntryText.Append(行);
}
}
返回值;
}
}
类日志
{
公共字符串文本;
公共日期时间入口日期;
PublicJournalEntry(字符串文本,DateTime entryDate)
{
this.Text=文本;
this.EntryDate=EntryDate;
}
}
}

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

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

currentEntryDate=新的日期时间()


如果您真的不想实例化代码,那么您的代码将无法正常工作。

DateTime? currentEntryDate = null

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

像这样重新构造循环怎么样?这将确保
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();
}

在这种情况下,编译器无法实现
hitFirstEntry
currentEntryDate
之间的“依赖性”

即使您可以“证明”只要
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;
        }

不可以。但是有效的代码必须在访问所有局部变量之前为它们分配一个值,并且编译器必须保证这一点。我敢肯定这是一个重复项。@pst:那么我如何向编译器保证这一点呢?这是编译器确保在变量有值之前不使用变量的方法。编译器无法从复杂的条件语句中确定
currentEntryDate
在您使用它之前将有一个值,因此它会抛出该错误。在这里给
currentEntryDate
一个初始值是这样一个悲剧吗?相关@pst:你为什么把这个问题作为一个重复的问题来投票?这完全是一个dif