将 objects 添加到 IEnumerable
Adding objects to IEnumerable
我正在制作一个基本的 CSV Reader。我使用 header
和 data
从内容中分离出 header。
现在,我的列表包含 person 类型的数据。:
public class person
{
public int id;
public string name;
public int age;
public person(string id, string name, string age)
{
try
{
this.id = Convert.ToInt32(id);
this.name = name;
this.age = Convert.ToInt32(age);
}
catch (FormatException e)
{
Console.WriteLine(e.Message);
}
}
public string ToString()
{
return $"{id}, {name}, {age}";
}
}
现在我喜欢使用类型 data
并创建一个存储信息的类型 person
。现在我正在尝试对所有内容使用 IEnumerable<>
,因为这里的许多评论都说它更适合内存管理。现在,由于它的行为与 List<T>
有点不同,所以我在制作存储人员的类型时遇到了问题。我在使用 IEnumerable
时左右都有错误,所以我懒得写下我糟糕的代码。
var data = file.Skip(1).Select(p => p.Split(';'));
IEnumerable<person> listofperson;
我的问题是,如何使用 IEnumerable<>
完成这项工作?或者我什至应该关心并选择 List<>
?
IEnumerable<T>
只是一个接口,不是实现。如果你看它的定义,它只支持 'enumerate' 的能力。您正在寻找一个接口和一个基础类型,它支持将类型添加到某种集合的能力。如果您查看 ICollection<T>
,您会发现它建立在 IEnumerable<T>
的枚举功能之上,添加了对管理集合内容的支持。用于此目的的典型类型是 List<T>
。我会从那里开始,用对象填充你的List<Person>
。一旦你有了这个 Person
的列表,你就可以使用接口 List<T>
实现来控制它的使用方式。例如,如果您只想在 List<Person>
上提供枚举支持,则可以将其强制转换为 IEnumerable<Person>
,从而缩小焦点范围。
var myPeople = new List<Person>();
/// populate the list
myPeople.Add(new Person());
/// provide 'focussed' interface to underlying type
IEnumerable<Person> enumerablePeople = myPeople;
还有其他类型实现 ICollection<T>
,具有不同的特性,但是,List<T>
可能是您需要的最简单的起点。
还有IEnumerable.Append。如果您想在不制作完整副本的情况下将一个额外的项目附加到一个大列表中,这很好,但在添加许多项目时不适合使用。
我可能会建议使用 iterator block
public IEnumerable<Person> GetData(){
...
var lines = file.Skip(1);
foreach(var line in lines){
var cells = line.Split(';');
var person = new Person(...);
yield return person;
}
}
这是一种编写惰性 reader 来根据需要处理数据的简单而紧凑的方法。但请注意,每次迭代 IEnumerable 时都会进行此解析。所以在很多情况下,你做的第一件事就是将它转换为列表。
我会小心关于内存管理的声明。如果您正在处理大文件,像这样的某种流解决方案确实很关键,但您需要非常小心,这样您就永远不需要将所有文件都保存在内存中。但是,在处理小文件时,一次完成所有处理可能会更有效率。或者在两者之间做一些事情,比如处理数据块。这实际上取决于您的用例以及内存和性能要求。
我正在制作一个基本的 CSV Reader。我使用 header
和 data
从内容中分离出 header。
现在,我的列表包含 person 类型的数据。:
public class person
{
public int id;
public string name;
public int age;
public person(string id, string name, string age)
{
try
{
this.id = Convert.ToInt32(id);
this.name = name;
this.age = Convert.ToInt32(age);
}
catch (FormatException e)
{
Console.WriteLine(e.Message);
}
}
public string ToString()
{
return $"{id}, {name}, {age}";
}
}
现在我喜欢使用类型 data
并创建一个存储信息的类型 person
。现在我正在尝试对所有内容使用 IEnumerable<>
,因为这里的许多评论都说它更适合内存管理。现在,由于它的行为与 List<T>
有点不同,所以我在制作存储人员的类型时遇到了问题。我在使用 IEnumerable
时左右都有错误,所以我懒得写下我糟糕的代码。
var data = file.Skip(1).Select(p => p.Split(';'));
IEnumerable<person> listofperson;
我的问题是,如何使用 IEnumerable<>
完成这项工作?或者我什至应该关心并选择 List<>
?
IEnumerable<T>
只是一个接口,不是实现。如果你看它的定义,它只支持 'enumerate' 的能力。您正在寻找一个接口和一个基础类型,它支持将类型添加到某种集合的能力。如果您查看 ICollection<T>
,您会发现它建立在 IEnumerable<T>
的枚举功能之上,添加了对管理集合内容的支持。用于此目的的典型类型是 List<T>
。我会从那里开始,用对象填充你的List<Person>
。一旦你有了这个 Person
的列表,你就可以使用接口 List<T>
实现来控制它的使用方式。例如,如果您只想在 List<Person>
上提供枚举支持,则可以将其强制转换为 IEnumerable<Person>
,从而缩小焦点范围。
var myPeople = new List<Person>();
/// populate the list
myPeople.Add(new Person());
/// provide 'focussed' interface to underlying type
IEnumerable<Person> enumerablePeople = myPeople;
还有其他类型实现 ICollection<T>
,具有不同的特性,但是,List<T>
可能是您需要的最简单的起点。
还有IEnumerable.Append。如果您想在不制作完整副本的情况下将一个额外的项目附加到一个大列表中,这很好,但在添加许多项目时不适合使用。
我可能会建议使用 iterator block
public IEnumerable<Person> GetData(){
...
var lines = file.Skip(1);
foreach(var line in lines){
var cells = line.Split(';');
var person = new Person(...);
yield return person;
}
}
这是一种编写惰性 reader 来根据需要处理数据的简单而紧凑的方法。但请注意,每次迭代 IEnumerable 时都会进行此解析。所以在很多情况下,你做的第一件事就是将它转换为列表。
我会小心关于内存管理的声明。如果您正在处理大文件,像这样的某种流解决方案确实很关键,但您需要非常小心,这样您就永远不需要将所有文件都保存在内存中。但是,在处理小文件时,一次完成所有处理可能会更有效率。或者在两者之间做一些事情,比如处理数据块。这实际上取决于您的用例以及内存和性能要求。