如何遍历C#对象中的所有字段?

时间:2018-11-16 08:07:40

标签: c# reflection

我有一个这样的对象:

public class Filters {
    public int var1 = 1, 
          var2 = 2, 
          var3 = 3;
}

我在这里声明此对象:

Filters filter1 = new Filters();

我想循环访问var1var2var3并对其进行处理。即:

foreach (var prop in filter1.props) {
    Console.WriteLine(filter1[prop] + 3);
}

,输出将是:

4
5
6

我想我需要为每个属性使用一个foreach循环 foreach(PropertyInfo p in filter1.GetType().GetProperties()),但我不知道如何1)遍历道具var1,var2,var3和2)如何使用存储在变量中的名称从filter1继承道具

3 个答案:

答案 0 :(得分:0)

如果您将变量描述为像下面这样的属性,

public class Filters
{
    public int var1 { get; set; } = 1;
    public int var2 { get; set; } = 2;
    public int var3 { get; set; } = 3;
}

您可以使用

访问这些属性
  

GetType()。GetProperties()

然后主要方法将给您您所要的

static void Main(string[] args)
{
    Filters filter1 = new Filters();

    foreach (var prop in filter1.GetType().GetProperties())
    {
        Console.WriteLine("{0}={1}", prop.Name, (int)prop.GetValue(filter1, null) + filter1.GetType().GetProperties().Length);
    }

    Console.ReadKey();
}

结果将是

4
5
6

答案 1 :(得分:0)

对于您的问题的另一种答案可能是以下内容,例如您有类似以下内容的过滤器

public class Filter 
{
    public IDictionary<string, object> Properties { get; } = new Dictionary<string, object>();
}

这将使您拥有一组动态的过滤器,可以将新属性分配为使用者,并迭代现有属性。这似乎符合您当前的要求。

至于一个真正的答案,正如评论中许多指出的那样,如果要迭代properties,则应该实际使用它们。在示例代码中,您提供了fields

所以您的类Filter可能最终看起来像这样(请注意,我认为var1 ... var3是您可以使用的最可怕的名称,因为我无法想象它们最终会定义什么):< / p>

public class Filter 
{
    public int Var1 { get; set; } = 1;
    public int Var2 { get; set; } = 2;
    public int Var3 { get; set; } = 3;
}

然后您可能会遇到类似的东西:

var filter = new Filter();
var filterType = filter.GetType();
var readableProperties = filterType.GetProperties().Where( p => p.GetGetMethod() != null );

foreach (var property in readableProperties) 
{
    var value = (int)property.GetValue( filter );
    Console.WriteLine( $"{property.Name} =  {value + 3}" );
}

为确保只选择您真正想要的名称,您当然可以检查名称是否等于Var1,Var2,Var3或匹配正则表达式,或者您想想到的任何东西;)

这里的代码示例,您可以在此dotnetfiddle中找到(尽管没有自动属性和$)

答案 2 :(得分:0)

感谢所有回答的人-几个提示帮助我到达了那儿。我刚开始使用C#,所以我不知道字段/属性是什么,所以感谢@SeM @John。除此之外,还有@Icepickle和@arslanaybars的答案GetProperties(),但字段却是:

        FieldInfo[] fields = typeof(GeneralFilters).GetFields();
        for (int i = 0; i < fields.Length; i++)
        {
            //MANIPULATE HERE
            BlankTemplate tempFilter = (BlankTemplate)fields[i].GetValue(filters);
            // Ignore this for now.       tempFilter.selectedItems;
        }

在此处定义BlankTemplate的地方:

public class BlankTemplate
{
    public string[] selectedItems;
    public bool selectAll = false;
}

现在在tempFilter中,我有了在每次迭代中都需要使用的对象

谢谢!

编辑:我意识到这不能回答如何使用对象字段的字符串化名称进行子集化的问题。我之前设想的是生成字段名数组,然后使用字段名循环遍历和子集字段中的数据,例如javascript:

var fieldNames = Object.keys(filterObject);
for (var i = 0; i < fieldNames.length; i++) {
    doSomething( filterObject[fieldNames[i]] );
}

但是在C#中似乎有些不同