我想用反射遍历我的Car类来删除所有空值并用更好的值替换它们,比如string =“”。
[Serializable()]
public class Car
{
public string model;
public int year;
public List<Owner> owner;
}
[Serializable()]
public class Owner
{
public string firstName;
public string lastName;
}
到目前为止,我已经做到了这一点
public void LoopEverythingAndFix(object type)
{
var prop = type.GetType().GetFields();
foreach (var fieldInfo in prop)
{
if (GetType(fieldInfo))
{
var value = fieldInfo.GetValue(type);
if (value == null)
fieldInfo.SetValue(type, GetDefaultValue(fieldInfo));
}
else
{
LoopEverythingAndFix(fieldInfo);
}
}
}
public bool GetType(System.Reflection.FieldInfo fieldInfo)
{
if (fieldInfo.FieldType == typeof(string))
return true;
if (fieldInfo.FieldType == typeof(bool))
return true;
if (fieldInfo.FieldType == typeof(int))
return true;
if (fieldInfo.FieldType == typeof(decimal))
return true;
return false;
}
GetType
方法是知道当前字段是否类似于“所有者”类,或者它的值/引用字段是否类似于int / string,如果它是“所有者”类型,那么我想要将它循环到并修复这些属性。
问题在于它在汽车类中找到“所有者”,然后执行:
LoopEverythingAndFix(fieldInfo);
问题所在,因为我将fieldInfo
发送给方法LoopEverythingAndFix
,当它返回循环时,它会在type.GetType().GetFields()
获得0个字段。这是一个列表,我想循环列表项并将它们发送到LoopEverythingAndFix方法
答案 0 :(得分:3)
您尝试在反射类型LoopEverythingAndFix
上调用FieldInfo
,而不是要修复的实际对象。
要解决此问题,请将其替换为:
LoopEverythingAndFix(fieldInfo);
有了这个:
LoopEverythingAndFix(fieldInfo.GetValue(type));
答案 1 :(得分:0)
似乎问题在于,您传递的是对静态类所有者的引用,而不是传递一个Owner对象。所以你已经拥有了所有者的类型。
答案 2 :(得分:0)
您的代码存在一些问题需要解决:
您正在对已知值类型执行空检查。除Nullable<T>
之外的ValueType实例永远不会为null。此操作是不必要的,会影响性能。我在下面解决了这个问题。
您没有考虑string
以外的空引用类型字段的情况。例如,如果存在空Owner
或空List<Owner>
,会发生什么?
由于您没有发布GetDefaultValue()
函数,因此它的签名有点不清楚。我的猜测是它接受FieldInfo
并根据字段类型解析默认的非空值。因为,实际上这仅适用于string
参数,最好用string.Empty
替换呼叫。我在下面的评论中指出了这一点。
下面,我在下面对您的功能进行了整合,优化和重写,并附有注释以指示必须更改或插入不同行为的位置。
public void LoopEverythingAndFix(object instance)
{
var fields = instance.GetType().GetFields(BindingFlags.Public|BindingFlags.Instance)
foreach(var fieldInfo in fields){
var fieldType = fieldInfo.FieldType;
if(!fieldType.IsValueType){
bool isString = fieldType == typeof(string);
var fieldValue = fieldInfo.GetValue(instance);
if(fieldValue != null){
if(!isString){
// This should recursion be called when the type is a
// complex (non-string) reference type that is not null
LoopEverythingAndFix(fieldValue);
}
// You don't need to fix a non-null string value
}
else{
if(isString){
// since you didn't post the code for this, I am assuming
// it works correctly, but it may be that you can just replace
// GetDefaultValue(fieldInfo) with string.Empty
fieldInfo.SetValue(instance, GetDefaultValue(fieldInfo));
}
else{
// It is unclear how you want to handle a complex reference type
// field with a null value. That code should go here.
}
}
}
}
}