我是C#新手,我真的很困惑我正在尝试为C#课程中的项目做些什么。
赋值是C#中的一些列表操作。
程序接受文本框中的项目列表,然后遍历这些项目,创建列表的多个副本。它随机地将列表的每个副本调整为3到所有项目。然后输出所有副本。
我遇到的问题是,当我使用调试器逐步执行此程序时,我得到了预期的输出。如果我在每次迭代后显示一个消息框(正如我在下面的代码中所示),也会发生同样的情况。
但是,如果我直接运行程序,我会得到不同的输出。而不是列表中的变化,列表的所有副本都完全相同。
如果你在代码中看到我评论了“// FIRST DEBUG MESSAGEBOX”和“// SECOND DEBUG MESSAGEBOX”。如果第一个调试消息框代码留在那里,输出就像预期的那样...输出列表的多个版本,随机长度介于3和所有项目之间。
然而,这就是我感到困惑的地方......如果你注释掉第一个调试消息框代码,你会得到不同的结果。列表输出的所有版本都是相同的长度,没有变化。
任何帮助将不胜感激!这是我到目前为止的代码...对不起,如果它很可怕 - 我是C#的新手:
public partial class MainForm : Form
{
/**
* Vars to hold raw text list items
* and list items split by line
*/
String rawListItems = "";
List<string> listItems = new List<string>();
List<List<string>> textListItems = new List<List<string>>();
public MainForm()
{
InitializeComponent();
}
private void cmdGo_Click(object sender, EventArgs e)
{
// store the contents of the list item text box
this.rawListItems = txtListItems.Text;
this.listItems.AddRange(Regex.Split(this.rawListItems, "\r\n"));
// setup min and max items - max items all items
int minItems = 3;
int maxItems = this.listItems.Count;
// We'll copy this list X times, X = same number of items in list
for (int i = 0; i < this.listItems.Count; i++)
{
// make a copy of the list items
List<string> listItemsCopy = new List<string>(this.listItems);
// get a random number between min items and max items
Random random = new Random();
int maxIndex = random.Next(minItems, maxItems + 1); // max is exclusive, hence the +1
// remove all elements after the maxIndex
for (int j = 0; j < listItemsCopy.Count; j++)
{
if (j > maxIndex)
{
listItemsCopy.RemoveAt(j);
}
}
// add the list copy to the master list
this.textListItems.Add(listItemsCopy);
// FIRST DEBUG MESSAGEBOX
String tst = "";
foreach (string item in listItemsCopy)
{
tst += item + " ## ";
}
MessageBox.Show(tst);
}
// SECOND DEBUG MESSAGEBOX
String output = "";
foreach (List<string> listitem in this.textListItems)
{
foreach (string item in listitem)
{
output += item + " ## ";
}
}
MessageBox.Show(output);
}
}
答案 0 :(得分:2)
将Random的创建移出循环:
Random random = new Random();
默认情况下,构造函数使用基于默认时间的种子。在一个紧密的循环中,你可能会得到“相同的”随机生成器而不是每个循环的不同生成器。
使用MessageBoxes或单步执行时,您允许计时器在每个循环中运行并获取“新的”随机生成器。
答案 1 :(得分:0)
我完全不明白你的作业,但这个循环似乎不正确:
for (int j = 0; j < listItemsCopy.Count; j++)
{
if (j > maxIndex)
{
listItemsCopy.RemoveAt(j);
}
}
当你删除列表中间的元素时,之后的元素会被移位,所以maxIndex
之后的所有元素都不会被删除,正如您所期望的那样。
答案 2 :(得分:0)
在调试器中逐步执行代码会影响程序行为的情况下,一种有用的替代调试技术是使用System.Diagnostics命名空间,特别是Trace类。
Trace函数的工作原理与Console.WriteLine()非常相似,您可以跟踪字符串或格式字符串以及对象数组以填充格式字符串,例如:
Trace.TraceInformation("some message that tells me something");
Trace.TraceInformation("some useful format string {1}, {0}",
new object[] {someObject, someOtherObject});