2011-06-18 42 views
5

领域我想有空值的字段,但我连是不是得到任何字段:得到与反思

[Serializable()] 
public class BaseClass 
{ 
    [OnDeserialized()] 
    internal void OnDeserializedMethod(StreamingContext context) 
    { 
     FixNullString(this); 
    } 

    public void FixNullString(object type) 
    { 
     try 
     { 
      var properties = type.GetType().GetFields(); 


      foreach (var property in from property in properties 
            let oldValue = property.GetValue(type) 
            where oldValue == null 
            select property) 
      { 
       property.SetValue(type, GetDefaultValue(property)); 
      } 
     } 
     catch (Exception) 
     { 

     } 
    } 

    public object GetDefaultValue(System.Reflection.FieldInfo value) 
    { 
     try 
     { 
      if (value.FieldType == typeof(string)) 
       return ""; 

      if (value.FieldType == typeof(bool)) 
       return false; 

      if (value.FieldType == typeof(int)) 
       return 0; 

      if (value.FieldType == typeof(decimal)) 
       return 0; 

      if (value.FieldType == typeof(DateTime)) 
       return new DateTime(); 
     } 
     catch (Exception) 
     { 

     } 

     return null; 
    } 
} 

然后,我有一个类:

[Serializable()] 
public class Settings : BaseClass 
{ 
    public bool Value1 { get; set; } 
    public bool Value2 { get; set; } 
} 

但是,当我来到到

​​

然后我得到0字段,它应该找到2个字段。

是type.getType()。GetFields()错误使用?还是我把错误的类发送给基类?

回答

13

Type.GetFields方法返回所有公共领域。编译器为你自动生成的字段是私有的,所以你需要指定正确的BindingFlags

type.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic) 
1

Value1Value2在你的Settings类是属性而不是字段,所以你需要使用GetProperties()来访问它们。

(使用{ get; set; }语法告诉你想要的属性的编译器,但它应该为您生成getset,与包含数据隐藏的私有字段一起。)

0

编译器生成的对应于您类的属性的字段具有CompilerGenerated属性。此外,编译器将根据您的财产声明生成getset方法来处理这些字段。

CompilerGeneratedAttribute MSDN文档:

区分用户产生的元件的编译器生成的元件。这个类不能被继承。

这些字段的名称的格式<PropertyName>k_BackingField,方法setget名称的格式set_PropertyNameget_PropertyName其中属性名是属性的名称。

例如,跟随你的Settings类编译:

[Serializable] 
public class Settings : BaseClass 
{ 
    public Settings(){} 

    // Properties 
    [CompilerGenerated] 
    private bool <Value1>k__BackingField; 

    [CompilerGenerated] 
    private bool <Value2>k__BackingField; 

    [CompilerGenerated] 
    public void set_Value1(bool value) 
    { 
     this.<Value1>k__BackingField = value; 
    } 

    [CompilerGenerated] 
    public bool get_Value1() 
    { 
     return this.<Value1>k__BackingField; 
    } 

    [CompilerGenerated] 
    public void set_Value2(bool value) 
    { 
     this.<Value2>k__BackingField = value; 
    } 

    [CompilerGenerated] 
    public bool get_Value2() 
    { 
     return this.<Value2>k__BackingField; 
    } 
} 

如果你想排除这种支持字段,你可以使用这个方法:

public IEnumerable<FieldInfo> GetFields(Type type) 
{ 
    return type 
     .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) 
     .Where(f => f.GetCustomAttribute<CompilerGeneratedAttribute>() == null); 
}