使用匿名类型返回IEnumerable

3

我有一个类似于这样的接口:

IEnumerable<(string valueA, decimal valueB)> GetData

这个接口不应该被更改。因此我正在尝试实现它。我需要使用LINQ,所以我有以下这部分代码:

var fetchedData = File.ReadAllLines(filePath)
                    .Skip(1)
                    .Select(a => x.Split(';'))
                    .Select(a => new 
                    {
                        valueB= decimal.Parse(a[0]),
                        valueA= a[1]
                    });
return fetchedData;

问题在于fetchedData的类型与接口所需的类型不同。我需要返回IEnumerable<(string valueA, decimal valueB)>,但是fetchedData是另一种类型。

2
为什么不使用元组呢?.Select(a => (a[1], decimal.Parse(a[0])); - Dmitry Bychenko
然后将其更正为正确的类型:.Select(a => (valueA: a[1], valueB: decimal.Parse(a[0]))。请注意匿名类型和值元组的不同语法;您的 IEnumerable 声明使用了后者。在此处添加成员名称是可选的,但我强烈建议这样做,因为它使得需要遵守顺序(与匿名类型不同)变得更加清晰。 - Jeroen Mostert
你不能返回一个匿名类型。但是你可以返回一个 Tuple - Franck
(string valueA, decimal valueB) 不是匿名类型,而是元组。 - Enigmativity
@hunter44 顺便说一下,也许最好使用一个库来解析你的CSV文件... 没必要重复造轮子。 - ˈvɔlə
4个回答

3

在你的选择中返回一个带有名称的元组,而不是匿名对象 :)

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])));

我撤销了你对问题所做的更改,因为我觉得你让原问题的提出者似乎知道他们在做什么——但实际上并非如此。原始问题提供了更多的背景信息。 - Enigmativity

3
您在这里混淆了匿名类型值元组
虽然您的接口返回一个元组,但是您的LINQ查询生成了一个匿名类型。请将您的查询更改为:
var fetchedData = File.ReadAllLines(filePath)
    .Skip(1)
    .Select(a => x.Split(';'))
    .Select(a => (a[1], decimal.Parse(a[0])));

3

您的代码存在一些问题:

  1. Your interface expects the result to be a Tuple<string, decimal> which is the actual type behind the notation (string valueA, decimal valueB)

  2. 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.

以下是修复您的代码以满足接口的解决方案:

var fetchedData = File.ReadAllLines(filePath)
                .Skip(1)
                .Select(a => x.Split(';'))
                .Select(a => (a[1], decimal.Parse(a[0]) ) );
return fetchedData;

2
如果接口坚持使用元组(命名元组),那么我们就提供它:
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]));

您只需要将{..}改为(...),并保持正确的顺序(先是string再是decimal)。您可以添加名称,但这不是必需的:

return File
  .ReadLines(filePath)
  .Skip(1)
  .Select(a => x.Split(';'))
  .Select(a => (valueA : a[1], valueB : decimal.Parse(a[0]));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接