C# 在方法外部访问对象的多个实例

C# 在方法外部访问对象的多个实例,c#,winforms,C#,Winforms,我有一个名为Vehicle的类和一个名为Car的类,它们继承自Vehicle。我有一个表格,你可以通过填写一些信息并点击一个按钮来创建一个汽车对象。此信息将插入到gridview中 我想做的是通过我创建的ID访问一个特定的汽车对象 我创建了一个ID来标识每个汽车对象。我希望能够访问某个对象,比如ID为3的Car对象 我有一个组合框,我想填充所有的汽车ID,这样我以后可以选择一个特定的汽车对象并克隆它,例如。我使用一个事件检查添加到DataGridView的行。添加行时,应在组合框中添加车辆id

我有一个名为
Vehicle
的类和一个名为
Car
的类,它们继承自
Vehicle
。我有一个表格,你可以通过填写一些信息并点击一个按钮来创建一个汽车对象。此信息将插入到gridview中

我想做的是通过我创建的ID访问一个特定的汽车对象

我创建了一个ID来标识每个汽车对象。我希望能够访问某个对象,比如ID为3的Car对象

我有一个组合框,我想填充所有的汽车ID,这样我以后可以选择一个特定的汽车对象并克隆它,例如。我使用一个事件检查添加到
DataGridView
的行。添加行时,应在组合框中添加
车辆id

我遇到的问题是,如果检查
行加载
,则无法访问对象
testCar
。我试图在
按钮单击
事件外部声明对象实例,然后在
按钮单击
事件内部更改该对象,但这不起作用。我在想,也许我需要创建一个对象数组,在其中插入每个不同的汽车

这是我的密码:

class Car : Vehicle
{
    string carBrand = "";
    private static int carID { get; set; }
    public int iD { get; set; }
    public string CarBrand { get; set; }
    public Color CarColor { get; set; }
    public Car()
    {
        carID = 0;
        CarBrand = "Volvo";
        CarColor = Color.Black;
    }
    public Car(string vehicleName, int vehicleYear, string carBrand, Color carColor)
    {
        this.iD = GetNextCarID();
        this.VehicleName = vehicleName;
        this.VehicleYear = vehicleYear;
        this.CarBrand = carBrand;
        this.CarColor = carColor;
    }
    static Car() 
    {
        carID = 0;

    }
    protected int GetNextCarID()
    {
        return ++carID;
    }


    public void button1_Click(object sender, EventArgs e)
    {

        string inputModell = txtModell.Text;
        int inputCarYear = Int16.Parse(txtCarYear.Text);
        string inputBrand = cmbCarBrands.SelectedItem.ToString();
        Color inputColor = Color.Black;
        if (colorDialog1.Color != Color.Black)
        {
            inputColor = colorDialog1.Color;
        }
        Car testCar = new Car(inputModell, inputCarYear, inputBrand, inputColor);
        int id = testCar.iD;

        if (txtModell.Text != string.Empty && txtCarYear.Text != string.Empty)
        {                
            dataGridView1.ColumnCount = 6;
            dataGridView1.Columns[0].Name = "ID";
            dataGridView1.Columns[1].Name = "Modell";
            dataGridView1.Columns[2].Name = "Årtal";
            dataGridView1.Columns[3].Name = "Märke";
            dataGridView1.Columns[4].Name = "Färg";
            dataGridView1.Columns[5].Name = "Orginal/Klon";
            int currRow = dataGridView1.Rows.Add(testCar.iD, testCar.VehicleName, testCar.VehicleYear, testCar.CarBrand, "", "Orginal");
            DataGridViewCellStyle cellStyle = new DataGridViewCellStyle();
            cellStyle.BackColor = testCar.CarColor;
            dataGridView1.Rows[currRow].Cells[4].Style = cellStyle; 
        }
    }

    private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
    {
        groupBox2.Enabled = true;
        cmbCarID.Items.Add(testCar.iD);
    }

是的,听起来你想要一系列的汽车,类似这样的东西

class Car : Vehicle
{
    ...

    List<Car> CarList;
    public Car()
    {
        CarList = new List<Car>  // do this in each constructor
        ...
    }

    ...


    public void button1_Click(object sender, EventArgs e)
    {
        Car car = new Car();

        ...

        CarList.Add(car);
    }
}
车辆类别:车辆
{
...
卡利斯特名单;
公共汽车
{
CarList=new List//在每个构造函数中执行此操作
...
}
...
公共无效按钮1\u单击(对象发送者,事件参数e)
{
汽车=新车();
...
添加(汽车);
}
}

另一方面,我不知道
Car
类是否是
按钮的最合适位置

一本
字典
就是为这样的任务制作的

在表单上创建一个
字典作为字段:

private Dictionary<int, Car> carLookup = new Dictionary<int, Car>();
现在,您可以使用字典通过ID轻松查找汽车:

public Car GetCar(int id)
{
    return carLookup[id];
}
不需要收集! 通过访问datagridview的最后一行,可以访问添加到datagridview的最后一辆车

private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
    int lastRowIndex = dataGridView1.Rows.Count-1;
    int carId = int.Parse(dataGridView1.Rows[lastRowIndex].Cells[0].Value.ToString());
    groupBox2.Enabled = true;
    cmbCarID.Items.Add(carId);
}

为什么在
Car
类中有按钮点击和数据网格突变?这真的是你的代码的组织方式,还是在这里发布时出现了错误?将UI与业务逻辑分开。
Car
类应该对按钮之类的概念一无所知。对此表示抱歉。事件按钮Click不在car类中,它完全位于不同的类文件中。buttonclick位于“main”类文件中,如果您可以这样称呼它的话。对不起,总数为n00b;9) 嗯,好的。假设我创建了一个包含5辆不同汽车的列表。如何访问列表中的特定汽车?如果您有链接,您可以执行类似CarList.Where(cl=>cl.iD=myID).First()的操作。@user1987473您也可以通过list@SamIam列表不是为搜索而设计的。您应该使用专门为高效搜索而设计的数据结构,例如字典。@Servy List可以更好地用于小数据集,但字典即使在项目数增加到非常高的值时仍保持相同的性能。但一般来说,在搜索“是”时使用字典是一个很好的规则。我更习惯于使用数据库。在sql中,我会从carID=3的汽车中选择*。我会从那辆车上取下值,然后用它做一些事情,比如更新或克隆它。这正是我想用这个汽车物体做的。是否没有简单快捷的方法来访问已创建的每个对象?我可能需要做一些完全不同的事情HeHeHe一旦添加新行,它的id就会插入到组合框中。稍后,他可以使用这些ID并从datagridviewit中检索其他信息,当我尝试此操作时,它会给出错误信息。无法将带[]的索引应用于“System.Windows.forms.DataGridViewRow”类型的表达式。这是到此部分的链接:dataGridView1.Rows[lastRowIndex][0]抱歉!尝试以下操作:int.Parse(dataGridView1.Rows[lastRowIndex].Cells[0].Value.ToString());我还在回答中编辑了它。新错误:NullReferenceException未处理。对象引用未设置为对象的实例。很抱歉,它是一个总的n00b,但是我应该将GetCar方法放在哪里?我得到一个关于不一致的可访问性的错误。可访问性不一致:返回类型“\u 4stepbystep.Car”比方法“\u 4stepbystep.v3start.GetCar(int)”更难访问。我将字典和GetCar方法直接放在表单后面class@user1987473类别
Car
应为
public
。把它放在类型定义之前。没过多久,下一个问题就来了呵呵。如何循环遍历汽车对象的所有现有实例。我试了一会儿,我null GetCar(i),i++但整数永远不能为null。实际上我想我解决了它。foreach(carLookup中的KeyValuePair car)@Xerion您可以这样做,尽管我个人喜欢使用这种模式:
foreach(carLookup.Keys中的int key){car value=carLookup[key];}
foreach
使用字典时。不过他们俩都很好。
private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
    int lastRowIndex = dataGridView1.Rows.Count-1;
    int carId = int.Parse(dataGridView1.Rows[lastRowIndex].Cells[0].Value.ToString());
    groupBox2.Enabled = true;
    cmbCarID.Items.Add(carId);
}