1

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;
   }
}
4

6 に答える 6

1

再帰を試すことができます + Concat

public static IEnumerable<FieldInfo> GetAllFields(Type objectType)
{
   if (objectType == null)
      return Enumerable<FieldInfo>.Empty;
   else 
      return objectType.GetFields(
                 BindingFlags.NonPublic | BindingFlags.Public |
                 BindingFlags.Instance | BindingFlags.DeclaredOnly)
         .Concat(GetAllFields(objectType.BaseType));
}
于 2011-02-28T20:18:40.490 に答える
0

誰もが指摘したように、問題は、生成された要素の型が期待される型と一致しないことです。

毎回 for/while/foreach を書くのを避けるために、反復を処理する拡張メソッドを使用するのが好きです。

public static class Sequence
{
    public static IEnumerable<T> Create<T>(T seed, Func<T, bool> predicate, Func<T, T> next)
    {
        for (T t = seed; predicate(t); t = next(t))
            yield return t;
    }
}

そうすれば、はるかに読みやすいクエリを記述してフィールドを返すことができます

public static IEnumerable<FieldInfo> GetAllFields(Type objectType)
{
    BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
    return from type in Sequence.Create(objectType, t => t != null, t => t.BaseType)
        from field in type.GetFields(flags)
        select field;
}
于 2011-02-28T20:59:27.850 に答える
0

少し再帰はどうですか?

public static IEnumerable<FieldInfo> GetAllFields(Type objectType)
{      
      //GetFields(...) returns a FieldInfo []
      var fields = objectType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
      if(objectType.BaseType==null) return fields;
      return fields.Concat(GetAllFields(object.BaseType));
 }
于 2011-02-28T20:24:51.047 に答える