i具有以下扩展方法,该方法从同一类的源对象中填充了类成员的缺失值。该方法的缺失部分是当课程的成员也是其他班级的班级对象时,也有自己的成员,所以我在这里需要递归,但是我找不到任何方法来吸引任何方法班级成员并能够将其传递给FillValues
方法...
例如,我有一个名为User
的类,一个称为UserLogin
的类:
public class User
{
public string FirstName;
public string LastName;
public UserLogin Login;
}
public class UserLogin
{
public string Email;
public string Password;
}
当我在类User
的成员上调用FillValues
时,如果填充FirstName
和LastName
的缺失字段,而不是从Login
中填写,因为它也是类成员。
如何递归通过成员Login
,以便嵌套成员也将填充值?
public static void FillValues<T>(this T target, T source)
{
FillMissingProperties(target, source);
FillMissingFields(target, source);
}
private static void FillMissingProperties<T>(T target, T source)
{
var properties = typeof(T).GetProperties().Where(prop => prop.CanRead && prop.CanWrite);
foreach (var prop in properties)
{
var targetValue = prop.GetValue(target, null);
var defaultValue = prop.PropertyType.GetTypeInfo().IsValueType ? Activator.CreateInstance(prop.PropertyType) : null;
if (targetValue == null || targetValue.Equals(defaultValue))
{
var sourceValue = prop.GetValue(source, null);
prop.SetValue(target, sourceValue, null);
}
}
}
private static void FillMissingFields<T>(T target, T source)
{
var fields = typeof(T).GetFields();
foreach (var field in fields)
{
var targetValue = field.GetValue(target);
var sourceValue = field.GetValue(source);
var defaultValue = field.FieldType.GetTypeInfo().IsValueType ? Activator.CreateInstance(field.FieldType) : null;
if (targetValue == null || targetValue.Equals(defaultValue))
field.SetValue(target, sourceValue);
}
}
您需要递归地调用类类型的类字段/属性的FillValues
。为此,您需要具有此方法的非通用版本:
public static void FillValues<T>(this T target, T source)
{
FillValues(typeof(T), target, source);
}
private static void FillValues(Type type, object target, object source)
{
FillMissingProperties(type, target, source);
FillMissingFields(type, target, source);
}
private static void FillMissingProperties(Type type, object target, object source)
{
var properties = type.GetProperties().Where(prop => prop.CanRead && prop.CanWrite);
foreach (var prop in properties)
{
var targetValue = prop.GetValue(target, null);
var defaultValue = prop.PropertyType.GetTypeInfo().IsValueType ? Activator.CreateInstance(prop.PropertyType) : null;
if (targetValue == null || targetValue.Equals(defaultValue))
{
var sourceValue = prop.GetValue(source, null);
prop.SetValue(target, sourceValue, null);
}
else if (targetValue != null && prop.PropertyType != typeof(string) && prop.PropertyType.GetTypeInfo().IsClass)
{
var sourceValue = prop.GetValue(source, null);
FillValues(prop.PropertyType, targetValue, sourceValue);
}
}
}
private static void FillMissingFields(Type type, object target, object source)
{
var fields = type.GetFields();
foreach (var field in fields)
{
var targetValue = field.GetValue(target);
var sourceValue = field.GetValue(source);
var defaultValue = field.FieldType.GetTypeInfo().IsValueType ? Activator.CreateInstance(field.FieldType) : null;
if (targetValue == null || targetValue.Equals(defaultValue))
{
field.SetValue(target, sourceValue);
}
else if(targetValue != null && field.FieldType != typeof(string) && field.FieldType.GetTypeInfo().IsClass)
{
FillValues(field.FieldType, targetValue, sourceValue);
}
}
}