System.Reflection的GetProperties方法不返回值

33

请问为什么如果类的设置如下,GetProperties 方法不能返回公共值?

public class DocumentA
{
    public string AgencyNumber = string.Empty;
    public bool Description;
    public bool Establishment;
}

我正在尝试设置一个简单的单元测试方法来进行实验。

该方法如下,并且它具有所有适当的using语句和引用。

我所做的一切就是调用以下内容,但它返回0。

PropertyInfo[] pi = target.GetProperties(BindingFlags.Public | BindingFlags.Instance);

但是,如果我使用私有成员和公共属性设置类,它就可以正常工作。

我没有按照传统的方式设置类的原因是因为它有61个属性,这样做会至少将我的代码行数增加到三倍。那将是一个维护噩梦。


4
很明显,这个类没有属性,只有字段。当你允许类像这样扩张时,噩梦就开始了。使用公共字段会让你失眠更多。 - Hans Passant
4个回答

61

你还没有声明任何属性 - 你声明的是字段。这里是使用属性的类似代码:

public class DocumentA
{
    public string AgencyNumber { get; set; }
    public bool Description { get; set; }
    public bool Establishment { get; set; }

    public DocumentA() 
    {
        AgencyNumber = "";
    }
}

我强烈建议您使用上述属性(或者可能更受限制的setter),而不是仅仅改用 Type.GetFields。公共字段违反了封装性。(公共可变属性在封装方面并不是很好,但至少它们提供了一个API,其实现可以稍后更改。)


我完全同意您使用属性而不是字段的观点。我只是不知道正确的语法。通常我会声明私有字段和公共的getter和setter。我的问题在于,我以为我正在使用属性,但实际上我缺少了{get,set}。感谢您的澄清。 - gsirianni
这个答案真的帮了我很大的忙。 - Code Whisperer

4

因为你现在声明类的方式是使用字段。如果你想通过反射访问这些字段,那么你应该使用Type.GetFields()(请参见Types.GetFields Method1

我不知道你在使用哪个版本的C#,但在C# 2中,属性语法已经改变为如下所示:

public class Foo
{
  public string MyField;
  public string MyProperty {get;set;}
}

这难道不能减少代码量吗?

谢谢你的回答。我只是语法混乱了。我通常不会这样声明属性。大多数时候,我都有对应的私有字段的公共属性。 - gsirianni
2
但是为什么呢?使用简写语法编译成相同的IL。编译器会为您生成后端字段。只有在您想要在getter或setter中进行其他处理时,才需要更详细的语法。 - Wouter de Kort

2

我看到这个帖子已经四年了,但我仍然不满意提供的答案。提问者应该注意,他引用的是字段而不是属性。要动态重置所有字段(防止扩展),可以尝试以下方法:

/**
 * method to iterate through Vehicle class fields (dynamic..)
 * resets each field to null
 **/
public void reset(){
    try{
        Type myType = this.GetType(); //get the type handle of a specified class
        FieldInfo[] myfield = myType.GetFields(); //get the fields of the specified class
        for (int pointer = 0; pointer < myfield.Length ; pointer++){
            myfield[pointer].SetValue(this, null); //takes field from this instance and fills it with null
        }
    }
    catch(Exception e){
        Debug.Log (e.Message); //prints error message to terminal
    }
}

请注意,由于明显的原因,GetFields() 仅能访问公共字段。

这个答案回答了关于字段的初始问题,即使作者错误地在字段上使用了GetProperties()。谢谢! - Aaron Reed

1

如前所述,这些是字段而不是属性。属性语法应该是:

public class DocumentA  { 
    public string AgencyNumber { get; set; }
    public bool Description { get; set; }
    public bool Establishment { get; set;}
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接