I have an interface similar to this:
IEnumerable<(string valueA, decimal valueB)> GetData
This interface should not be changed. So I'm trying to implement it. I need to use LINQ, so I have this part of code:
var fetchedData = File.ReadAllLines(filePath)
.Skip(1)
.Select(a => x.Split(';'))
.Select(a => new
{
valueB= decimal.Parse(a[0]),
valueA= a[1]
});
return fetchedData;
The problem is that fetchedData
is not of the same type the interface expects. I need to return IEnumerable<(string valueA, decimal valueB)>
but fetchedData
is another type.
CodePudding user response:
You are confusing Anonymous Types and Value Tuples here.
While your interface returns a tuple, your LINQ query yields an anonymous type. Change your query to:
var fetchedData = File.ReadAllLines(filePath)
.Skip(1)
.Select(a => x.Split(';'))
.Select(a => (a[1], decimal.Parse(a[0])));
CodePudding user response:
There are a few issues with your code:
Your interface expects the result to be a
Tuple<string, decimal>
which is the actual type behind the notation(string valueA, decimal valueB)
Your code, particularly the following line:
.Select(a => new { valueB= decimal.Parse(a[0]), valueA= a[1] })
produces an anonymous object with the following fields
{ decimal valueB; string valueA; }
. The problem is that the .NET will declare a class to represent the anonymous type, and that is incompatible with the Tuple type you initially request from the interface.
Here is a fix for your code that should satisfy the interface:
var fetchedData = File.ReadAllLines(filePath)
.Skip(1)
.Select(a => x.Split(';'))
.Select(a => (a[1], decimal.Parse(a[0]) ) );
return fetchedData;
CodePudding user response:
Just return a named tuple in your select, instead of an anonymous object :)
IEnumerable<(string valueA, decimal valueB)> GetData()
=> File.ReadAllLines(filePath)
.Skip(1)
.Select(a => a.Split(';')) // here, you used x instead of a
.Select(a => (valueA: a[1], valueB: decimal.Parse(a[0])));
CodePudding user response:
If the interface insist on tuple (named tuple), let's provide it:
return File // let's drop fetchedData and just return
.ReadLines(filePath) // Let's drop All - premature materialization
.Skip(1)
.Select(a => x.Split(';'))
.Select(a => (a[1], decimal.Parse(a[0]));
All you have to do is to change {..}
into (...)
and keep the right order (first string
than decimal
). You may want to put the names, but it's not required:
return File
.ReadLines(filePath)
.Skip(1)
.Select(a => x.Split(';'))
.Select(a => (valueA : a[1], valueB : decimal.Parse(a[0]));