0

トピックのタイトルが正しいかどうかはわかりませんが、ここに私が欲しいものがあります。

クラスがあり、そのクラスが別のクラスを持つことができるとしましょう。

私が望むのは、クラスのフィールドを、最終的に複数のレベルを持つ List ジェネリックで取得することです。

たとえば、私がこれを持っているとしましょう:

class address
{
public string street;
public string number;
}

class Student
{
public string name;
public string surname;
public address addr;
}

たとえば、メソッドが必要です

Student s;
getItems(s);

名前、姓、および通りと番号を含む別のリストを含むリストが返されます。

私はこれを試しました:

public void getItems(Object o, List<object> list)
        {
            FieldInfo[] f = new FieldInfo[o.GetType().GetFields().Length];

           f = o.GetType().GetFields();                            

            foreach (FieldInfo fi in f)
            {                    
                if (fi.GetType().GetFields().Length > 0)
                {
                    List<object> newList = new List<object>();
                    list.Add(newList);

                    getItems(fi, newList);
                }
                else
                {
                    list.Add(fi.Name);
                }
            }                                                
        }

しかし、それは最初のレベルにしか到達しません。最初のパラメータは分解したいオブジェクトで、2 番目のパラメータはクラスを返すリスト オブジェクトです。みんな助けてくれませんか?ありがとう。

4

3 に答える 3

1

この種のことは、進むべき道を見つけるためのテストを書くのに最適です!

要するに、必要な方法は次のようなものです。

        List<string> GetFieldNames(IEnumerable<FieldInfo> fields)
        {
            var results = new List<string>();

            foreach (var fieldInfo in fields)
            {
                if (fieldInfo.FieldType.GetFields().Count() > 1)
                {
                    results.AddRange(GetFieldNames(fieldInfo.FieldType.GetFields()));
                }
                else
                {
                    results.Add(fieldInfo.Name);
                }
            }
            return results;
        }

関数 (および私の理解) を示す完全なテスト クラスは次のとおりです。

using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NUnit.Framework;

namespace stackoverflow_tests
{
    [TestFixture]
    public class ReflectionTest
    {
        class Address
        {
            public string Street;
            public string Number;
        }

        class Student
        {
            public string Name;
            public string Surname;
            public Address Address;
        }

        [Test]
        public void ShouldDisplayNestedClassFields()
        {
            var student = new Student();
            var studentFields = student.GetType().GetFields();

            Assert.IsNotNull(studentFields);
            Assert.AreEqual(3, studentFields.Count());

            var expectedNames = new []{"Name", "Surname", "Address"};
            var expectedTypes = new[] {typeof(string), typeof(string), typeof(Address)};

            for (var fieldIndex = 0; fieldIndex < 3; fieldIndex++)
            {
                var field = studentFields[fieldIndex];
                var fieldName = field.Name;
                Assert.AreEqual(expectedNames[fieldIndex], fieldName);

                var fieldType = field.FieldType;
                Assert.AreEqual(expectedTypes[fieldIndex], fieldType);

                var childFields = field.FieldType.GetFields();
                var childFieldCount = childFields.Count();
                var expectedFieldCount = fieldIndex == 2 ? 2 : 1;
                Assert.AreEqual(expectedFieldCount, childFieldCount);
            }
        }

        [Test]
        public void CanGetFieldNames()
        {
            var expectedResults = new List<string> {"Name", "Surname", "Street", "Number"};
            var student = new Student();
            var actual = GetFieldNames(student.GetType().GetFields());
            Assert.AreEqual(expectedResults, actual);
        }

        List<string> GetFieldNames(IEnumerable<FieldInfo> fields)
        {
            var results = new List<string>();

            foreach (var fieldInfo in fields)
            {
                if (fieldInfo.FieldType.GetFields().Count() > 1)
                {
                    results.AddRange(GetFieldNames(fieldInfo.FieldType.GetFields()));
                }
                else
                {
                    results.Add(fieldInfo.Name);
                }
            }
            return results;
        }

    }
}
于 2013-08-30T19:07:43.580 に答える