我正在運行一個型別為 otherOrders 的物件回圈,然后在另一個 for 回圈中更改物件值并復制到同一個串列中,但每次我更改新值時,前一個值都會被覆寫。請建議我如何不更改以前的值
List<OtherOrder> otherOrders = calling some function and getting value;
foreach (var otherOrder in otherOrders.ToList())
{
var docs = OtherOrdersManager.GetOtherOrderDeliveryDocumentAttachments(otherOrder.Id);
if (docs.Count > 1)
{
for (var i = 0; i < docs.Count; i )
{
otherOrder.ResultDate = docs[i].DocumentCreationText;
otherOrders.Add(otherOrder);
}
}
我想更改結果日期值而不覆寫前一個值并將其保存在相同或另一個串列中也可以。如果您對實體和克隆有任何疑問,請使用代碼提出建議。請幫忙
uj5u.com熱心網友回復:
第一個問題,在使用回圈變數時要更加小心,因為以與 fullList 相同的方式命名它非常令人困惑,特別是對于我們不能只將滑鼠懸停在變數上查看它的型別的人,我看到的另一個問題是您更改了.ResultDate實際 obj 的 ,然后將其再次添加到主串列中,您應該做的是洗掉 ,otherOrders.Add(otherOrder);因為您已經在更新主串列中的值,如果您想創建一個新串列并從中填充它一開始只需將代碼更改為:
List<OtherOrder> otherOrders = calling some function and getting value;
var newList = new List<otherOrder>();
foreach (var order in otherOrders.ToList())
{
var docs = OtherOrdersManager.GetOtherOrderDeliveryDocumentAttachments(order.Id);
if (docs.Count > 1)
{
for (var i = 0; i < docs.Count; i )
{
order.ResultDate = docs[i].DocumentCreationText;
newList.Add(order);
}
}
有一件事很高興知道,有時當你做這樣的事情時,newList.Add(otherOrder); 它只是創建一個指向值的指標order(這意味著當 order 的值改變時,內部的值newList也會改變,我們應該做的是手動添加新串列中的每個引數,這可以確保這些值沒有指向我們之前使用的主 lst:
newList.Add(new otherOrder()
{
param1 = order.param1,
param2 = order.param2
// go on until you set up all the params
});
所以嘗試這些方法中的任何一種,并告訴我它是否適合你,但最重要的是名稱問責制,所以在其他一切之前記住這一點!
uj5u.com熱心網友回復:
這是顯示明顯問題的 2 行:
otherOrder.ResultDate = docs[i].DocumentCreationText;
otherOrders.Add(otherOrder);
這里otherOrder已經是otherOrders串列中的一個專案。聽起來此時您真正想做的是創建 的克隆或副本,otherOrder更改ResultDate并將其添加到串列中。
僅從這個邏輯來看,為什么要克隆整個訂單而只更改日期并不明顯,它可能在您的業務環境中有效,但從當前代碼中不清楚。未來的編輯可能會誤解這個邏輯,所以我建議將變數名稱更改為更具描述性,并在其中包含某種型別的注釋。
從 OO 的角度來看,有多種方法可以實作物件的克隆,如果您想確保要克隆物件的所有邏輯實體都以相同的方式進行操作,那么這是一種行為物件型別,您應該將該邏輯封裝在該型別的定義中。
最初在 c# 中,您可以實作IClonable介面,但強烈建議不要這樣做:
注意:如果您需要一種克隆機制,請定義您自己的方法
Clone或Copy方法,并確保您清楚地記錄它是深拷貝還是淺拷貝。一個合適的模式是:public <type> Copy();
您如何實際實作這取決于您,但它應該涉及new您的OtherOrder型別實體的實體化以及要復制到新物件中的屬性和/或欄位的初始化。
雖然從性能角度來看不是最有效的,但您可以使用序列化以最少的代碼復制物件,這是使用Json.NET的一個非常簡單的解決方案
public OtherOrder Copy()
{
var cereal = JsonConvert.SerializeObject(value);
return (OtherOrder)JsonConvert.DeserializeObject(cereal, typeof(OtherOrder));
}
您還可以在工廠或靜態實用程式類中定義此Copy邏輯,甚至將其轉換為通用或擴展方法。但是您可以定義和控制如何克隆/復制物件實體。
包括使用這個方法,我在你的邏輯中添加了詳細的偽代碼注釋來突出每個動作的意圖:
// 1. Get a list of `OtherOrders`
List<OtherOrder> otherOrders = calling some function and getting value;
// 2. Create a copy of the list, and then iterate the items
// NOTE: This is a standard convention that allows us to
// iterate the original list using `foreach` whilst making changes to it
foreach (var order in otherOrders.ToList())
{
// 3. for each order, get the attachments
var docs = OtherOrdersManager.GetOtherOrderDeliveryDocumentAttachments(otherOrder.Id);
// 4. If there is more than 1 attachment, then we need to duplicate the order
// The external system can only process individual documents
if (docs.Count > 1)
{
// for each attachment, copy the original order, but transfer the unique information
// into the clone. Then put this new object into the original list.
foreach (var attachment in docs)
{
var orderClone = otherOrder.Copy();
orderClone.ResultDate = attachment.DocumentCreationText;
otherOrders.Add(orderClone);
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/447662.html
