C# 中的列表<struct> VS 列表<class>
List<struct> VS List<class> in C#
我创建了一个基于结构的列表,但无法更改项目值。所以我使用 class 而不是结构,但是当我打印列表时出现问题,它根据项目的数量给我插入了重复的最新项目。
例如。如果我插入 "A" , "B" , "C" 那么输出将是 C C C 而不是 A B C
这是代码:
public struct Item //this is working fine but can't change item price
{
public string Code { get; set; }
public string Description{ get; set; }
public string Price{ get; set; }
public string Qty { get; set; }
}
public static Class Item //this is not working it's overwrite the last value
{
public string Code { get; set; }
public string Description{ get; set; }
public string Price{ get; set; }
public string Qty { get; set; }
}
其余代码
public static Item xItem = new Item();
public static List<Item> item = new List<Item>();
xItem.Code = txtCode.Text;
xItem.Description = txtDescription.text;
xItem.Price= txtPrice.text;
xItem.Qty = txtQty.text;
这两个我都试过了(给出了相同的结果)
item.Insert(i,xItem);
// and
item.Add(xItem);
在btnSave_Click
我加这个
foreach (var s in item)
{
System.Diagnostics.Debug.WriteLine(s.Code +" \t " + s.Qty);
}
对于 struct
版本...您没有理由不能更改结构中的值。你能更完整地解释你在那里遇到的问题吗?我怀疑它与使用 static
有关,这似乎在这里没有位置......但问题中没有足够的信息让我们确定。
对于class
版本,每次要添加条目需要创建一个newItem
实例:
//why are these static? That seems like a bad idea, but we lack enough context to know for sure
public static Item xItem;
public static List<Item> item = new List<Item>();
xItem = new Item();
xItem.Code = txtCode.Text;
xItem.Description = txtDescription.text;
xItem.Price= txtPrice.text;
xItem.Qty = txtQty.text;
这将使您可以将多个 class 实例添加到列表中...但如果我的怀疑是正确的,那么您将遇到与使用 struct
时相同的情况,我发现罪魁祸首可能是 static
。
这是由于 reference- and value-types semantics。 reference-type (=class) 只是一个指向实例的指针。因此,当您将一个对象传递给方法时,您实际上提供了一个指向该对象的指针,而不是实际的对象。您通过该引用更改的所有内容都会反映在对该实例的所有引用上。
在您的情况下,您只有一个引用用于不同的实例语义。因此创建一个新实例而不是重新使用现有实例:
public static Item xItem = new Item();
public static List<Item> item = new List<Item>();
...
xItem = new Item();
xItem.Code = txtCode.Text;
xItem.Description = txtDescription.text;
xItem.Price= txtPrice.text;
xItem.Qty = txtQty.text;
顺便说一句,结构通常应该是不可变的。因此,每当您打算修改实例状态时,您应该考虑使用 class 而不是结构。要进一步阅读有关不变性的信息,您还可以阅读此 post:Why are C# structs immutable?
您正在创建 Item
的静态实例并将其命名为 xItem
然后您设置 xItem
的属性并将其添加到您的列表 - item
item
现在包含 1 个项目 - xItem
然后您再次设置 xItem
的属性 - 并再次添加到列表中。
这是问题所在。您的列表现在包含 2 个项目 - 2 个对 xItem
的引用 - 不是 2 个不同的对象,而是同一个对象,两次。
...第三次。
您的代码需要更改为:
public static List<Item> item = new List<Item>();
//repeat this for each instance / 'version' of `Item` you want to add to your list.
// note the `new` keyword
var xItem = new Item();
xItem.Code = txtCode.Text;
xItem.Description = txtDescription.text;
xItem.Price= txtPrice.text;
xItem.Qty = txtQty.text;
item.Add(xItem);
听起来您正在重复使用 xItem
对象。
您需要为列表中的每个项目创建一个新项目。该列表只是一个对象引用列表,目前它们都指向同一个实际对象。
例如此代码:
public static Item xItem = new Item();
public static List<Item> list = new List<Item>();
xItem.Code = "A";
xItem.Description = "A";
xItem.Price= "1";
xItem.Qty = "1";
list.Add(xItem);
//list now has 'A' with value of 1 in it..
xItem.Code = "B"
//without any further change, list will now have the same
//item, so its Code will now be "B":
//this will be TRUE:
var listIsNowB = (list[0].Code == "B");
相反,您需要这样做:
xItem.Code = "A";
xItem.Description = "A";
xItem.Price= "1";
xItem.Qty = "1";
list.Add(xItem);
//we're now done with that *instance* of Item, so we now create a *new* one.
//we can re-use our variable without problem though.
xItem = new Item();
xItem.Code = "B";
xItem.Description = "B";
xItem.Price= "2";
xItem.Qty = "2";
//xItem is a new object, so this will work as you expect now.
list.Add(xItem);
class
是一个引用类型,所以如果你调用一个方法,if 只会将引用传递给对象。 struct
是一种值类型,这意味着它会在您调用方法时创建对象的完整副本,除非您使用 in
或 ref
调用它。
您需要做的是在每次插入时创建 class 的新实例。
像这样
item.Add(new Item
{
Code = txtCode.Text,
...
});
我创建了一个基于结构的列表,但无法更改项目值。所以我使用 class 而不是结构,但是当我打印列表时出现问题,它根据项目的数量给我插入了重复的最新项目。
例如。如果我插入 "A" , "B" , "C" 那么输出将是 C C C 而不是 A B C
这是代码:
public struct Item //this is working fine but can't change item price
{
public string Code { get; set; }
public string Description{ get; set; }
public string Price{ get; set; }
public string Qty { get; set; }
}
public static Class Item //this is not working it's overwrite the last value
{
public string Code { get; set; }
public string Description{ get; set; }
public string Price{ get; set; }
public string Qty { get; set; }
}
其余代码
public static Item xItem = new Item();
public static List<Item> item = new List<Item>();
xItem.Code = txtCode.Text;
xItem.Description = txtDescription.text;
xItem.Price= txtPrice.text;
xItem.Qty = txtQty.text;
这两个我都试过了(给出了相同的结果)
item.Insert(i,xItem);
// and
item.Add(xItem);
在btnSave_Click
我加这个
foreach (var s in item)
{
System.Diagnostics.Debug.WriteLine(s.Code +" \t " + s.Qty);
}
对于 struct
版本...您没有理由不能更改结构中的值。你能更完整地解释你在那里遇到的问题吗?我怀疑它与使用 static
有关,这似乎在这里没有位置......但问题中没有足够的信息让我们确定。
对于class
版本,每次要添加条目需要创建一个newItem
实例:
//why are these static? That seems like a bad idea, but we lack enough context to know for sure
public static Item xItem;
public static List<Item> item = new List<Item>();
xItem = new Item();
xItem.Code = txtCode.Text;
xItem.Description = txtDescription.text;
xItem.Price= txtPrice.text;
xItem.Qty = txtQty.text;
这将使您可以将多个 class 实例添加到列表中...但如果我的怀疑是正确的,那么您将遇到与使用 struct
时相同的情况,我发现罪魁祸首可能是 static
。
这是由于 reference- and value-types semantics。 reference-type (=class) 只是一个指向实例的指针。因此,当您将一个对象传递给方法时,您实际上提供了一个指向该对象的指针,而不是实际的对象。您通过该引用更改的所有内容都会反映在对该实例的所有引用上。
在您的情况下,您只有一个引用用于不同的实例语义。因此创建一个新实例而不是重新使用现有实例:
public static Item xItem = new Item();
public static List<Item> item = new List<Item>();
...
xItem = new Item();
xItem.Code = txtCode.Text;
xItem.Description = txtDescription.text;
xItem.Price= txtPrice.text;
xItem.Qty = txtQty.text;
顺便说一句,结构通常应该是不可变的。因此,每当您打算修改实例状态时,您应该考虑使用 class 而不是结构。要进一步阅读有关不变性的信息,您还可以阅读此 post:Why are C# structs immutable?
您正在创建 Item
的静态实例并将其命名为 xItem
然后您设置 xItem
的属性并将其添加到您的列表 - item
item
现在包含 1 个项目 - xItem
然后您再次设置 xItem
的属性 - 并再次添加到列表中。
这是问题所在。您的列表现在包含 2 个项目 - 2 个对 xItem
的引用 - 不是 2 个不同的对象,而是同一个对象,两次。
...第三次。
您的代码需要更改为:
public static List<Item> item = new List<Item>();
//repeat this for each instance / 'version' of `Item` you want to add to your list.
// note the `new` keyword
var xItem = new Item();
xItem.Code = txtCode.Text;
xItem.Description = txtDescription.text;
xItem.Price= txtPrice.text;
xItem.Qty = txtQty.text;
item.Add(xItem);
听起来您正在重复使用 xItem
对象。
您需要为列表中的每个项目创建一个新项目。该列表只是一个对象引用列表,目前它们都指向同一个实际对象。
例如此代码:
public static Item xItem = new Item();
public static List<Item> list = new List<Item>();
xItem.Code = "A";
xItem.Description = "A";
xItem.Price= "1";
xItem.Qty = "1";
list.Add(xItem);
//list now has 'A' with value of 1 in it..
xItem.Code = "B"
//without any further change, list will now have the same
//item, so its Code will now be "B":
//this will be TRUE:
var listIsNowB = (list[0].Code == "B");
相反,您需要这样做:
xItem.Code = "A";
xItem.Description = "A";
xItem.Price= "1";
xItem.Qty = "1";
list.Add(xItem);
//we're now done with that *instance* of Item, so we now create a *new* one.
//we can re-use our variable without problem though.
xItem = new Item();
xItem.Code = "B";
xItem.Description = "B";
xItem.Price= "2";
xItem.Qty = "2";
//xItem is a new object, so this will work as you expect now.
list.Add(xItem);
class
是一个引用类型,所以如果你调用一个方法,if 只会将引用传递给对象。 struct
是一种值类型,这意味着它会在您调用方法时创建对象的完整副本,除非您使用 in
或 ref
调用它。
您需要做的是在每次插入时创建 class 的新实例。
像这样
item.Add(new Item
{
Code = txtCode.Text,
...
});