I am new to C# and OOP, in general, I've kinda hit a wall I am reading in this CSV using the CSV Helper package, but there are some unwanted rows, etc so I have cleaned it up by iterating over "records" and creating a new class LineItems.
But Now I appear to be a bit stuck. I know void doesn't return anything and is a bit of a placeholder. But How can I access all the instances of LineItems outside of this function?
public void getMapper()
{
using (var StreamReader = new StreamReader(@"D:\Data\Projects\dictUnitMapper.csv"))
{
using (var CsvReader = new CsvReader(StreamReader, CultureInfo.InvariantCulture))
{
var records = CsvReader.GetRecords<varMapper>().ToList();
foreach (var item in records)
{
if (item.name != "#N/A" && item.priority != 0)
{
LineItems lineItem = new LineItems();
lineItem.variableName = item.Items;
lineItem.variableUnit = item.Unit;
lineItem.variableGrowthCheck = item.growth;
lineItem.variableAVGCheck = item.avg;
lineItem.variableSVCheck = item.svData;
lineItem.longName = item.name;
lineItem.priority = item.priority;
}
}
}
}
}
public class LineItems
{
public string variableName;
public string variableUnit;
public bool variableGrowthCheck;
public bool variableAVGCheck;
public bool variableSVCheck;
public string longName;
public int priority;
}
public class varMapper
{
public string Items { get; set; }
public string Unit { get; set; }
public bool growth { get; set; }
public bool avg { get; set; }
public bool svData { get; set; }
public string name { get; set; }
public int priority { get; set; }
}
CodePudding user response:
You can return a collection of LineItems from the function:
Change your LineItems class name to LineItem.
Change return type of GetMapper function from void to something that represents a collection. Using IEnumerable in example below, it would be a good choice if you don't need to alter the collection after returning.
public IEnumerable<LineItem> GetMapper()
{
...
// Don't call .ToList, let GetRecords return a yielded IEnumerable
var records = CsvReader.GetRecords<varMapper>();
var lineItems = new List<LineItem>();
foreach (var item in records)
{
var lineItem = new LineItem();
// map
lineItems.Add(lineItem);
}
return lineItems;
}
Not to jump too far ahead, but if you do not want to load the entirety of the file into a list in memory, you can/should utilize yield
public IEnumerable<LineItem> GetMapper()
{
...
// Don't call .ToList, let GetRecords return a yielded IEnumerable
var records = CsvReader.GetRecords<varMapper>();
foreach (var item in records)
{
var lineItem = new LineItem();
// map
yield return lineItem;
}
}
CodePudding user response:
You should write your method to return a list.
public List<LineItems> GetMapper()
{
using (var StreamReader = new StreamReader(@"D:\Data\Projects\dictUnitMapper.csv"))
{
using (var CsvReader = new CsvHelper.CsvReader(StreamReader, CultureInfo.InvariantCulture))
{
return
CsvReader
.GetRecords<varMapper>()
.Where(item => item.name != "#N/A")
.Where(item => item.priority != 0)
.Select(item => new LineItems()
{
variableName = item.Items,
variableUnit = item.Unit,
variableGrowthCheck = item.growth,
variableAVGCheck = item.avg,
variableSVCheck = item.svData,
longName = item.name,
priority = item.priority,
})
.ToList();
}
}
}
Here's an alternative syntax for building the return value:
return
(
from item in CsvReader.GetRecords<varMapper>()
where item.name != "#N/A"
where item.priority != 0
select new LineItems()
{
variableName = item.Items,
variableUnit = item.Unit,
variableGrowthCheck = item.growth,
variableAVGCheck = item.avg,
variableSVCheck = item.svData,
longName = item.name,
priority = item.priority,
}
).ToList();