我正在尝试访问我在创建新对象时创建的按钮内的数组,但是当我使用它时按钮超出数组边界(但是访问按钮外部的相同索引没有问题) )
相关代码(请参阅下面的类别和费用类别):
public void updateExpensesLabels()
{
deleteExpensesLabels();
for (int i = 0; i < categories.Length; i++)
{
if (categories[i] != null)
{
categories[i].test();
addExpense.Click += (s, e) =>
{
categories[i].createNewExpense(Convert.ToInt32(expenseAmount.Text), Convert.ToString(expenseName.Text));
};
}
}
}
请注意,类别[i]没有任何问题,并打印出应有的随机文本,但是当我将测试放在按钮内时,单击按钮时问题就会消失。
编辑:我使测试更加明显,这一次,代码的输出是&#34;对象在按钮之外不是空的&#34;因为索引超出数组
而粉碎 if (categories[i] == null)
{
MessageBox.Show("Its null outside the button code");
}
else
{
MessageBox.Show("Its not null outside the button code");
}
addExpense.Click += (s, e) =>
{
if (categories[i] == null)
{
MessageBox.Show("Its null inside the button code");
}
categories[i].test();
categories[i].createNewExpense(Convert.ToInt32(expenseAmount.Text), Convert.ToString(expenseName.Text));
};
编辑2: System.IndexOutOfRangeException是个例外 细节 -
System.IndexOutOfRangeException occurred
HResult=0x80131508
Message=האינדקס נמצא מחוץ לגבולות המערך.
Source=Budget Managment Prog
StackTrace:
at Budget_Managment_Prog.Form1.<>c__DisplayClass21_0.<updateExpensesLabels>b__0(Object s, EventArgs e) in C:\Users\user\OneDrive\Budget Management Prog\Budget Managment Prog\Budget Managment Prog\Form1.cs:line 213
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at Budget_Managment_Prog.Program.Main() in C:\Users\user\OneDrive\Budget Management Prog\Budget Managment Prog\Budget Managment Prog\Program.cs:line 19
Forms1 -
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Budget_Managment_Prog
{
/// <summary>
/// Expenses Section
/// </summary>
Category[] categories = new Category[0];
TabPage[] categoryTab = new TabPage[0];
Label[] expenseLabel = new Label[0];
private void addCategoryButton_Click(object sender, EventArgs e)
{
increaseCategories();
categories[Category.categoryNum] = new Category(Category.categoryNum, newCategoryTextBox.Text);
Category.categoryNum++;
increaseTabs();
updateExpensesLabels();
}
private void increaseTabs()
{
TabPage[] temp = new TabPage[categoryTab.Length + 1];
for (int i = 0; i < categoryTab.Length; i++)
{
temp[i] = categoryTab[i];
}
categoryTab = temp;
}
private void increaseCategories()
{
Category[] temp = new Category[categories.Length + 1];
for (int i = 0; i < categories.Length; i++)
{
temp[i] = categories[i];
}
categories = temp;
}
public void updateExpensesLabels()
{
deleteExpensesLabels();
for (int i = 0; i < categories.Length; i++)
{
if (categories[i] != null)
{
categoryTab[i] = new TabPage();
categoryTab[i].Text = categories[i].name;
categoryTabControl.Controls.Add(categoryTab[i]);
Label addExpenseLabel = new Label(); addExpenseLabel.Text = "New Expense Here?";
addExpenseLabel.AutoSize = true;
addExpenseLabel.Top = 10; addExpenseLabel.Left = 15; categoryTab[i].Controls.Add(addExpenseLabel);
Label nameLabel = new Label(); nameLabel.Text = "Name:";
nameLabel.AutoSize = true;
nameLabel.Top = 25; nameLabel.Left = 25; categoryTab[i].Controls.Add(nameLabel);
Label amountLabel = new Label(); amountLabel.Text = "Money:";
amountLabel.AutoSize = true;
amountLabel.Top = 25; amountLabel.Left = 250; categoryTab[i].Controls.Add(amountLabel);
TextBox expenseName = new TextBox(); expenseName.Top = 50; expenseName.Left = 25; categoryTab[i].Controls.Add(expenseName);
TextBox expenseAmount = new TextBox(); expenseAmount.Top = 50; expenseAmount.Left = 250; categoryTab[i].Controls.Add(expenseAmount);
categories[i].test();
Button addExpense = new Button();
addExpense.Click += (s, e) =>
{
categories[i].createNewExpense(Convert.ToInt32(expenseAmount.Text), Convert.ToString(expenseName.Text));
};
categoryTab[i].Controls.Add(addExpense);
int entries = 0;
int labelNum = 0;
for (int j = 0; j < categories[i].expenses.Length; j++)
{
expenseLabel[labelNum] = new Label();
expenseLabel[labelNum].Text = Convert.ToString(categories[i].expenses[labelNum].num);
expenseLabel[labelNum].Top = 80 + (30 * entries); expenseLabel[labelNum].Left = 25;
categoryTab[i].Controls.Add(expenseLabel[labelNum]);
increaseLabelArray();
labelNum++;
}
}
}
}
private void deleteExpensesLabels()
{
for (int i = 0; i< categoryTab.Length; i++)
{
categoryTabControl.Controls.Remove(categoryTab[i]);
}
}
private void increaseLabelArray()
{
Label[] temp = new Label[expenseLabel.Length + 1];
for (int i = 0; i < expenseLabel.Length; i++)
{
temp[i] = expenseLabel[i];
}
expenseLabel = temp;
}
}
}
类别 -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Budget_Managment_Prog
{
class Category
{
private int numOfExpenses = 0;
public Expense[] expenses = new Expense[0];
public static int categoryNum = 0;
public string name;
public Category(int num1, string name1)
{
categoryNum = num1;
name = name1;
}
public void createNewExpense( int expense2, string name2)
{
increaseArray();
expenses[numOfExpenses] = new Expense(numOfExpenses, expense2, name2);
numOfExpenses ++;
}
public void deleteExpense(int num)
{
if (num > expenses.Length || num < 1)
{
MessageBox.Show("Invalid Entry for deletion, make sure the number is not bigger than the biggest person or smaller than 1");
}
else
{
Expense[] temp = new Expense[expenses.Length - 1];
for (int i = 0; i < expenses.Length; i++)
{
if (expenses[i].num < num)
{
temp[i] = expenses[i];
}
if (expenses[i].num > num)
{
expenses[i].num--;
temp[i - 1] = expenses[i];
}
}
expenses = temp;
numOfExpenses--;
}
}
public void increaseArray()
{
Expense[] temp = new Expense[expenses.Length + 1];
for (int i = 0; i < expenses.Length; i++)
{
temp[i] = expenses[i];
}
expenses = temp;
}
public void test()
{
MessageBox.Show("The Problem is in category or expense classes");
}
}
}
费用 -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Budget_Managment_Prog
{
class Expense
{
public int num;
public int expense;
public string name;
public Expense(int num1, int expense1, string name1)
{
num = num1;
expense = expense1;
name = name1;
}
}
}
答案 0 :(得分:2)
已更新
我找到了你的问题。它在categories[i]
中。如果您调试该程序,您会看到当您添加new Category
时i is 0
categories[i].test()
,button click
将正常运行。但问题在于,loop's iteration
总是在button click
之后,换句话说i
工作时equal to 1
已经categories[i]
而你的categories[i].test();
var number = i;
Button addExpense = new Button();
addExpense.Click += (s, e) =>
{
categories[number].createNewExpense(Convert.ToInt32(expenseAmount.Text), Convert.ToString(expenseName.Text));
};
1}}将超出界限
如果您更改代码中添加按钮的部分,您将不再获得异常:
public Expense[] expenses = new Expense[0];
您已宣布
expenses[numOfExpenses] = new Expense(numOfExpenses, expense2, name2);
然后你正在尝试这样做
numOfExpenses
expenses
超出length
List<Expense>
,因为它是您声明的空数组。
我建议您使用Expense[]
代替expenses.Add(new Expense(numOfExpenses, expense2, name2)).
,因此它不会受到您在初始化时提供的数量的限制,当您需要添加新的费用时,您将只是使用class Category
{
public List<Expense> expenses = new List<Expense>();
public static int categoryNum = 0;
public string name;
public Category(int num1, string name1)
{
categoryNum = num1;
name = name1;
}
public void createNewExpense(int expense2, string name2)
{
expenses.Add(new Expense(expenses.Count, expense2, name2));
}
public void deleteExpense(int num)
{
if (num > expenses.Count || num < 1)
{
MessageBox.Show("Invalid Entry for deletion, make sure the number is not bigger than the biggest person or smaller than 1");
}
else
{
expenses.RemoveAt(num);
}
}
public void test()
{
MessageBox.Show("The Problem is in category or expense classes");
}
}
以下是如何做到这一点的示例
serviceModel.read(
"/Users(1)", {
success: function(userModel) {
this.getView().setModel(userModel, "userAuthenticated");
},
error: function(error) {
},
context: this
}
);