用reflection得到领域
我想得到所有具有空值的字段,但我甚至得到任何字段:
[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; } }
但是当我来的时候
var properties = type.GetType().GetFields();
然后我得到0个字段,它应该找到2个字段。
是否使用type.getType()。GetFields()错误? 或者我在错误的class级中向基地派遣?
Type.GetFields方法返回所有公共字段。 编译器为您自动生成的字段是私有的,因此您需要指定正确的BindingFlags
。
type.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
Settings
类中的Value1
和Value2
是属性而不是字段,因此您需要使用GetProperties()
来访问它们。
(使用{ get; set; }
语法告诉编译器你想要一个属性,但它应该为你生成get
和set
,以及一个包含数据的隐藏私有字段。)
编译器生成的对应于类属性的字段具有CompilerGenerated属性。 此外,编译器将生成用于处理这些字段的get
和set
方法,具体取决于属性的声明。
来自CompilerGeneratedAttribute MSDN文档:
区分编译器生成的元素和用户生成的元素。 这个类不能被inheritance。
这些字段的名称格式为
,方法set
和get
names的格式为set_PropertyName
和get_PropertyName
,其中PropertyName是property的名称。
例如,您的Settings
类编译如下:
[Serializable] public class Settings : BaseClass { public Settings(){} // Properties [CompilerGenerated] private bool k__BackingField; [CompilerGenerated] private bool k__BackingField; [CompilerGenerated] public void set_Value1(bool value) { this.k__BackingField = value; } [CompilerGenerated] public bool get_Value1() { return this. k__BackingField; } [CompilerGenerated] public void set_Value2(bool value) { this.k__BackingField = value; } [CompilerGenerated] public bool get_Value2() { return this. k__BackingField; } }
如果您希望排除此支持字段,则可以使用此方法:
public IEnumerable GetFields(Type type) { return type .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) .Where(f => f.GetCustomAttribute() == null); }