获取具有反射的字段
本文关键字:字段 反射的 获取 | 更新日期: 2023-09-27 17:59:45
我想获得所有具有空值的字段,但我甚至无法获得任何字段:
[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个字段。
类型.getType().GetFields()使用错误吗?还是我把错误的类发送到基类?
Type.GetFields方法返回所有公共字段。编译器为您自动生成的字段是私有的,因此需要指定正确的BindingFlags
。
type.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
编译器生成的与类属性相对应的字段具有CompilerGenerated属性。此外,编译器将根据属性的声明生成用于处理这些字段的get
和set
方法。
来自编译器GeneratedAttributeMSDN文档:
区分编译器生成的元素和用户生成的元素。无法继承此类。
这些字段的名称格式为<PropertyName>k_BackingField
,方法set
和get
的名称格式分别为set_PropertyName
和get_PropertyName
,其中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);
}
Settings
类中的Value1
和Value2
是属性,而不是字段,因此需要使用GetProperties()
来访问它们。
(使用{ get; set; }
语法告诉编译器您需要一个属性,但它应该为您生成get
和set
,以及包含数据的隐藏私有字段。)