我基于struct创建了一个列表,但是无法更改项目值。所以我用了一个类而不是struct,但是当我打印列表时出现的问题是,根据项目数量,我插入了最新的项目。
例如如果我插入“ 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);
}
答案 0 :(得分:2)
听起来像您正在重新使用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);
答案 1 :(得分:1)
对于struct
版本来说,没有理由不应该更改结构中的值。您能否更全面地解释您在那里遇到的问题?我怀疑这与使用static
有关,这似乎在这里没有位置...但是问题中没有足够的信息让我们确定。
对于class
版本,每次要添加条目时都需要创建一个新 Item
实例:
//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;
这将使您可以将多个类实例添加到列表中...但是,如果我的怀疑是正确的,那么您将处于使用struct
时的情况,而我发现{ {1}}是元凶。
答案 2 :(得分:1)
您正在创建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);
答案 3 :(得分:1)
class
是引用类型,因此,如果您调用方法,则只会将引用传递给该对象。 struct
是一种值类型,这意味着除非您使用in
或ref
进行调用,否则它将在调用方法时创建对象的完整副本。
您需要做的是在每个插入上创建一个新的类实例。
像这样
item.Add(new Item
{
Code = txtCode.Text,
...
});
答案 4 :(得分:0)
这是由于reference- and value-types semantics造成的。 引用类型(= 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;
顺便说一句,结构通常应该是不可变的。因此,每当您打算修改实例状态时,都应考虑使用类而不是结构。要进一步了解不可变性,您还可以阅读以下文章:Why are C# structs immutable?