有没有办法调用在foreach功能块中声明的变量?

时间:2019-10-22 11:26:44

标签: c#

实例

List<BursaryPaymentSplitting> splitAccount = new List<BursaryPaymentSplitting>();

foreach ( var lineItem in splitAccount)
{
    var lineItems = new RemitaSplit { 
        lineItemsId = lineItem.BursaryPaymentSplittingId.ToString(), 
        beneficiaryName = lineItem.AccountName, 
        beneficiaryAccount = lineItem.AccountNumber, 
        bankCode = lineItem.BankCode, 
        beneficiaryAmount = lineItem.Amount.ToString(), 
        deductFeeFrom = lineItem.DeductFeeFrom.ToString() 
    };
}

我如何在lineItems功能块之外使用变量foreach

2 个答案:

答案 0 :(得分:2)

在所需范围内声明变量。例如:

RemitaSplit lineItems;
foreach (var lineItem in splitAccount)
{
    lineItems = new RemitaSplit { /.../ };
}
// Here you can access the lineItems variable.
// Though it *might* be NULL, your code should account for that.

尽管这里奇怪的是,您一次又一次地覆盖相同的变量。为什么?您是否要拥有对象的 collection 而不是一个对象?像这样吗?:

var lineItems = new List<RemitaSplit>();
foreach (var lineItem in splitAccount)
{
    lineItems.Add(new RemitaSplit { /.../ });
}
// Here you can access the lineItems variable.
// And this time it won't be NULL, though it may be an empty collection.

其中可能被简化为:

var lineItems = splitAccount.Select(lineItem => new RemitaSplit { /.../ });

在这种情况下,如何使用LINQ进行简化将取决于填充splitAccount的位置/方式。我假设问题中的示例只是人为设计的代码行,以显示该变量的类型,因为如果那是确切的代码,那么该循环当然永远不会遍历一个空列表。

要点是,如果splitAccount是一个表达式树,它将最终实现支持数据源中的数据,则您可能无法直接在new RemitaSplit()中调用.Select(),直到您将所有记录落实到内存中,例如使用.ToList(),并可能需要考虑性能。

答案 1 :(得分:1)

lineItems在整个foreach中都会发生变化。

让我们检查一下代码。

foreach ( var lineItem in splitAccount)
{
    var lineItems = new RemitaSplit { 

这将转换为以下内容:为splitAccount中的每个元素创建一个名为lineItems的新单个引用,并为其分配一个新的RemitaSplit对象。 lineItems的类型将是RemitaSplit,而不是List<RemitaSplit>

解决方案

我怀疑您需要类似以下内容的东西。

using System.Linq;

(...)

var lineItems = splitAccount.Select( lineItem =>  new RemitaSplit { ... } ).ToList();

foreach

var lineItems = new List<RemitaSplit>();
foreach ( var lineItem in splitAccount)
{
   //item, not items
   var lineItem = new RemitaSplit { 
       lineItemsId = lineItem.BursaryPaymentSplittingId.ToString(),
       (...)
   };
   lineItems.Add(lineItem);
}

编辑:json

  

我的目标是序列化lineItems并发布为json

using Newtonsoft.Json; 
using System.Linq;

(...)

var lineItems = splitAccount.Select( lineItem => 
    new RemitaSplit { 
        lineItemsId = lineItem.BursaryPaymentSplittingId.ToString(), 
        (...)
        }).ToList();

// Wrapping in an object, as an example, 
// the web doesn't like top level json arrays
// https://stackoverflow.com/questions/3503102/what-are-top-level-json-arrays-and-why-are-they-a-security-risk
// but what you send will be guided by the api the json is sent to. 
var json = JsonConvert.SerializeObject( new { Items = lineItems });