C# - 如何获取也是班级的类成员的属性



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时,如果填充FirstNameLastName的缺失字段,而不是从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);
        }
    }
}