You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何清理C#方法中的重复元素?.NET Core 3.1代码重构

优化方案

方案一:提取重复逻辑到私有方法

把每个属性的比较、更新逻辑封装成私有方法,消除重复代码的同时保持主方法的可读性:

public string Name { get; set; }
public string Description { get; set; }
// 其他string类型属性...

public bool MyMethod(Apple myApple)
{
    var flag = false;
    myApple.Id = Id;

    // 调用私有方法处理每个属性,用|=累积更新状态
    flag |= UpdateProperty(ref Name, myApple.Name);
    flag |= UpdateProperty(ref Description, myApple.Description);
    flag |= UpdateProperty(ref ShortDescription, myApple.ShortDescription);
    flag |= UpdateProperty(ref Location, myApple.Location);
    flag |= UpdateProperty(ref KindId, myApple.KindId);
    flag |= UpdateProperty(ref Expiration, myApple.Expiration);
    flag |= UpdateProperty(ref PurchaseDate, myApple.PurchaseDate);

    return flag;
}

// 封装单个属性的比较与更新逻辑
private bool UpdateProperty(ref string target, string source)
{
    if (target != source)
    {
        target = source;
        return true;
    }
    return false;
}

这种方式完全保留原逻辑,同时将重复的if块收拢到一个方法中,后续修改逻辑只需调整私有方法即可。

方案二:使用反射批量处理属性

如果后续会频繁新增属性,反射方案可以自动匹配当前类与Apple类的同名string属性,避免每次修改MyMethod:

public string Name { get; set; }
public string Description { get; set; }
// 其他string类型属性...

public bool MyMethod(Apple myApple)
{
    var flag = false;
    myApple.Id = Id;

    // 获取当前类所有可写的string属性
    var currentProps = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
        .Where(p => p.PropertyType == typeof(string) && p.CanWrite);

    foreach (var prop in currentProps)
    {
        // 匹配Apple类中同名的string属性
        var appleProp = typeof(Apple).GetProperty(prop.Name);
        if (appleProp == null || appleProp.PropertyType != typeof(string))
            continue;

        var currentValue = (string)prop.GetValue(this);
        var appleValue = (string)appleProp.GetValue(myApple);

        if (currentValue != appleValue)
        {
            prop.SetValue(this, appleValue);
            flag = true;
        }
    }

    return flag;
}

注意事项:

  • 反射存在轻微性能开销,适合属性较多或频繁变动的场景;若方法是高频调用,方案一更合适。
  • 需保证当前类与Apple类的属性名完全一致,否则无法自动匹配。

方案三:表达式树缓存(兼顾性能与灵活性)

如果想同时拥有反射的灵活性和直接调用的性能,可以用表达式树提前编译属性的读写方法并缓存:

// 静态缓存,避免重复编译表达式
private static readonly Dictionary<Type, Dictionary<string, (Func<object, string> Getter, Action<object, string> Setter)>> _propertyAccessors = new();

public string Name { get; set; }
public string Description { get; set; }
// 其他string类型属性...

public bool MyMethod(Apple myApple)
{
    var flag = false;
    myApple.Id = Id;

    var currentType = GetType();
    var appleType = typeof(Apple);

    // 初始化当前类的属性访问器缓存
    if (!_propertyAccessors.ContainsKey(currentType))
    {
        _propertyAccessors[currentType] = currentType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
            .Where(p => p.PropertyType == typeof(string) && p.CanWrite)
            .ToDictionary(
                p => p.Name,
                p => (
                    Getter: CreateGetter(p),
                    Setter: CreateSetter(p)
                )
            );
    }

    // 初始化Apple类的属性访问器缓存
    if (!_propertyAccessors.ContainsKey(appleType))
    {
        _propertyAccessors[appleType] = appleType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
            .Where(p => p.PropertyType == typeof(string))
            .ToDictionary(
                p => p.Name,
                p => (
                    Getter: CreateGetter(p),
                    Setter: null // Apple类仅需读取属性
                )
            );
    }

    var currentAccessors = _propertyAccessors[currentType];
    var appleAccessors = _propertyAccessors[appleType];

    foreach (var (propName, currentAccessor) in currentAccessors)
    {
        if (!appleAccessors.TryGetValue(propName, out var appleAccessor))
            continue;

        var currentValue = currentAccessor.Getter(this);
        var appleValue = appleAccessor.Getter(myApple);

        if (currentValue != appleValue)
        {
            currentAccessor.Setter(this, appleValue);
            flag = true;
        }
    }

    return flag;
}

// 创建属性的Getter表达式并编译
private static Func<object, string> CreateGetter(PropertyInfo prop)
{
    var param = Expression.Parameter(typeof(object));
    var castParam = Expression.Convert(param, prop.DeclaringType);
    var getProp = Expression.Property(castParam, prop);
    var castResult = Expression.Convert(getProp, typeof(string));
    return Expression.Lambda<Func<object, string>>(castResult, param).Compile();
}

// 创建属性的Setter表达式并编译
private static Action<object, string> CreateSetter(PropertyInfo prop)
{
    var instanceParam = Expression.Parameter(typeof(object));
    var valueParam = Expression.Parameter(typeof(string));
    var castInstance = Expression.Convert(instanceParam, prop.DeclaringType);
    var castValue = Expression.Convert(valueParam, prop.PropertyType);
    var setProp = Expression.Assign(Expression.Property(castInstance, prop), castValue);
    return Expression.Lambda<Action<object, string>>(setProp, instanceParam, valueParam).Compile();
}

该方案首次调用时编译表达式并缓存,后续调用性能接近直接代码调用,同时保留了自动处理属性的灵活性。

内容的提问来源于stack exchange,提问作者Bender.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 20:35:16