将数组序列 T myArray[] 转换为 IEnumerable在 c# 中
在下面的代码中,我想返回 IEnumerable 而不创建新的数据结构对象。但是,我收到以下代码的编译器错误。我缺少什么?
Error Cannot implicitly convert type 'System.Reflection.FieldInfo[]' to 'System.Reflection.FieldInfo'
public static IEnumerable<FieldInfo> GetAllFields(Type objectType)
{
while (objectType != null)
{
//GetFields(...) returns a FieldInfo []
yield return objectType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
objectType = objectType.BaseType;
}
}
In the following code I want to return an IEnumerable without creating a new data structure object. However, I get a compiler error with the following code. What am I missing?
Error Cannot implicitly convert type 'System.Reflection.FieldInfo[]' to 'System.Reflection.FieldInfo'
public static IEnumerable<FieldInfo> GetAllFields(Type objectType)
{
while (objectType != null)
{
//GetFields(...) returns a FieldInfo []
yield return objectType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
objectType = objectType.BaseType;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
Type.GetFields 返回 FieldInfo 对象的数组。
由于您没有返回数组的集合,因此您必须迭代该数组并返回其中的每个对象,有点像这样:
Type.GetFields returns an array of FieldInfo objects.
Since you´re not returning a collection of arrays, you have to iterate over the array and yield return each object in it, kinda like this:
yield return
对单个元素进行操作;您只需返回GetFields
的返回值即可达到您想要的效果。进一步解释一下,当您想要在将序列中的每个项目提供给调用者使用之前对其应用某些操作,但您又不想执行所有操作时,
yield return
主要有用预先工作并简单地以数组或List
形式返回聚合结果。yield return
使这个延迟执行易于编写,因为生成的迭代器块仅根据请求将任何此类操作应用于每个项目。编辑:抱歉 - 我错过了您的代码的要点之一(枚举基本字段),但我会保留这个答案,因为我认为它无论如何都可能有用。 Lasse Karlsen 的答案将满足您的需要,但除非您有一个巨大的类型层次结构,否则与仅聚合结果并将它们返回到数组相比,您并没有真正获得任何优势。
yield return
operates on single elements; you can simply return the return value fromGetFields
to achieve what you want.To explain further,
yield return
is mainly useful when you want to apply some operation to each item in a sequence before making it available to the caller, but you don't want to do all of that work up-front and simply return the aggregate results in an array orList<T>
.yield return
makes this deferred execution easy to write, because the generated iterator block only applies any such operation to each item as it's requested.EDIT: Sorry - I missed one of the points of your code (enumerating the base fields), but I'll leave this answer up since I think it might be useful anyway. Lasse Karlsen's answer will do what you need, but unless you have a huge type hierarchy, you're not really gaining any advantage over just aggregating the results and returning them in an array.
您可以尝试递归+Concat:
You can try recursion +
Concat
:您正在寻找的是“所有人的收益”。您必须遍历并产生返回从 GetFields 返回的每个项目,然后设置为基类。
但这不是必需的,因为有一个标志指示是否包含基类定义。
What you're looking for is a "yield forall." You'd have to foreach through and yield return each item returned from GetFields and then set to the base class.
This shouldn't be necessary though because there is a flag for whether or not to include base-class definitions.
稍微递归一下怎么样?
How about a little recursion?
正如大家所指出的,问题在于生成的元素的类型与预期的类型不匹配。
为了避免每次都编写 for/while/foreach,我喜欢使用扩展方法来为我处理迭代。
这样,您可以返回编写更具可读性的查询的字段
As everybody pointed out, the issue is that the type of the element yielded doesn't match with the type expected.
To avoid writing a for/while/foreach every time, I like to use an extension method that handles the iteration for me.
That way, you can return the fields writing a much more readable query