循环创建新对象并将其添加到 ArrayList [英] Looping to Create and Add New Objects to ArrayList

查看:88
本文介绍了循环创建新对象并将其添加到 ArrayList的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑以防止您阅读整篇文章tldr:对象的字段不应是静态的,除非您希望该对象的所有实例对该字段具有相同的值

Edit to save you from reading through this whole post tldr: an object's fields should not be static unless you want all instances of that object to have the same value for that field

我正在尝试创建和填充博客对象的 ArrayList.我知道这样做的通用方法:

I'm trying to create and populate an ArrayList of Blog objects. I do know the generic way do this:

create ArrayList of Blogs
loop (some condition)
     create new Blog
     add this Blog to AL

然而,当我尝试在 while(datareader.read()) 循环中这样做时,ArrayList 中的所有元素都是完全相同的博客.具体来说,我最终得到一个 ArrayList,其中填充了多个指向数据库表中最后一个 Blog 对象的指针.这是我的代码:

However, when I attempt to do so within the while(datareader.read()) loop, all of the elements in the ArrayList are exactly the same Blog. Specifically, I end up with an ArrayList filled with multiple pointers to the very last Blog object from the database table. Here is my code:

 public static ArrayList AllBlogs()
    {
        SqlDataReader dr = anonPage.ExecuteReader("SELECT * FROM Kristina_Blogs");

        ArrayList allBlogs = new ArrayList();

        if (dr.HasRows)
        {
            while (dr.Read())
            {
                Blog b = new Blog();

                //grab a row from Kristina_Blogs and assign those attributes to b
                b.setTitle(dr["title"].ToString());
                b.setMessage(dr["message"].ToString());
                b.setId(dr["id"]);

                allBlogs.Add(b);
            }
        }
        dr.Close();
        return allBlogs;
    }

正如我之前所说,这样做的结果是一个 ArrayList,其中填充了指向 Kristina_Blogs 表中最后一篇博客的指针.我想象 ArrayList allBlogs 看起来像 [b, b, b, ... b],因此当我说 b.setTitle() 等时它们都会更新.但是如果我创建一个新的博客对象,情况会怎样在每次迭代开始时?

As I said before, the result of this is an ArrayList filled with pointers to the very last blog from the Kristina_Blogs table. I imagine the ArrayList allBlogs looks like [b, b, b, ... b] and therefore they ALL get updated when I say b.setTitle() etc. But how can this be the case if I am creating a NEW Blog object at the beginning of each iteration?

以下是一些您不必阅读的额外信息,但它可能会消除对问题结构的一些混淆:

Here is some extra info that you don't have to read but it might clear up some confusion about the structure of the problem:

  1. 博客对象有 id、title 和 message 字段以及它们各自的 getter/setter
  2. Kristina_Blogs 是一个表,代表这些博客,其中包含 id、title、message 列
  3. 建议为我的数据库引擎添加一个标签,但我找不到它的标签:Microsoft SQL Server Management Studio
  4. 当我使用字符串的 ArrayList 而不是博客时,此代码完美运行

包括来自博客类的代码

public class Blog
{
    public App myApp;
    public static string Title;
    public static string Message;
    public static int Id;

    //constructors
    public Blog() { }
    public Blog(App App) { this.myApp = App; }

    //all getters and setters look like this
    public string getTitle() { return Title; }
    public void setTitle(string t) { Title = t; }

}

推荐答案

正如我在评论中提到的,您遇到的主要问题是您的成员变量是静态的,因此当您设置该值时,它们在所有实例中都会更改.你应该这样改变你的代码:

The main problem you have, as I mentioned in comments is your member variables are static, so when you set the value, they change in all instances. you should change your code this way:

public class Blog
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Message { get; set; }
}

以这种方式填写您的列表,不要忘记添加using System.Linq;:

And fill your list this way, don't forget to add using System.Linq;:

var result = new List<Blog>();
var connection = @"your connection string";
var command = "SELECT * FROM Kristina_Blogs";
var adapter = new System.Data.SqlClient.SqlDataAdapter(command, connection);
var dataTable = new DataTable();

//Get data
adapter.Fill(dataTable);

dataTable.Rows.Cast<DataRow>().ToList()
            .ForEach(row =>
            {
                var b = new Blog();
                b.Id = row.Field<int>("Id");
                b.Title = row.Field<string>("Title");
                b.Message = row.Field<string>("Message");

                result.Add(b);
            });

return result;

注意:

  • 当您创建成员时静态,它在该类的所有实例之间共享.
  • 在 C# 中,您可以使用 property 获取或设置值,你不需要setXsetY,当你获取一个属性的值时,get 代码该属性的一部分将执行,当您为属性赋值时,它的 set 部分将执行.你可以这样定义属性:
  • When you create a member static, it is shared between all instances of that calss.
  • In C# you can use property to get or set values, you don't need to setX or setY, when you get the value of a property, the get code of that property will execute and when you assign a value to a property the set part of it will execute. you can define properties this way:

属性:

private int id;
public int Id
{
    get
    {
        return id;
    }
    set
    {
        id = value;
    }
}

或更简单:

public int Id { get; set; }

这篇关于循环创建新对象并将其添加到 ArrayList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆