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