合并类的有效方法

时间:2014-10-09 10:49:02

标签: c# reflection

我有这堂课:

public class CompetitionBindingViewModel
{
    [Required]
    public string Name { get; set; }

    public string Description { get; set; }
}

public class CompetitionViewModel : CompetitionBindingViewModel
{
    public int Id { get; set; }
    public string Logo { get; set; }
    public string BackgroundImage { get; set; }
    public string ColourScheme { get; set; }
    public bool Current { get; set; }

    public CompetitionViewModel(Competition model)
    {
        this.Id = model.Id;
        this.Name = model.Name;
        this.Description = model.Description;
        this.Logo = model.Logo;
        this.BackgroundImage = model.BackgroundImage;
        this.ColourScheme = model.ColourScheme;
        this.Current = model.Current;
    }
}

正如您所看到的,这里有2个 ViewModels 。一个是首次创建竞争时(仅需要提供名称描述。在项目的后期我想分配一个徽标 BackgroundImage ColourScheme ,但这些不是必需的。 我还有一个当前值,默认设置为 False 。 我有这个功能处理所有这些:

[Route("")]
public async Task<IHttpActionResult> Put(CompetitionViewModel model)
{
    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    try
    {
        var competition = await this.service.GetAsync(model.Id);

        competition.Name = (string.IsNullOrEmpty(model.Name)) ? competition.Name : model.Name;
        competition.Description = (string.IsNullOrEmpty(model.Description)) ? competition.Description : model.Description;
        competition.Logo = (string.IsNullOrEmpty(model.Logo)) ? competition.Logo : model.Logo;
        competition.BackgroundImage = (string.IsNullOrEmpty(model.BackgroundImage)) ? competition.BackgroundImage : model.BackgroundImage;
        competition.ColourScheme = (string.IsNullOrEmpty(model.ColourScheme)) ? competition.ColourScheme : model.ColourScheme;
        competition.Current = (model.Current == competition.Current) ? competition.Current : model.Current;

        this.service.Update(competition);
    }
    catch (Exception ex)
    {
        return InternalServerError(ex);
    }

    return await base.SaveChanges();
}

现在,我喜欢整洁的代码,这只是不适合我。问题是这些问题:

competition.Name = (string.IsNullOrEmpty(model.Name)) ? competition.Name : model.Name;
competition.Description = (string.IsNullOrEmpty(model.Description)) ? competition.Description : model.Description;
competition.Logo = (string.IsNullOrEmpty(model.Logo)) ? competition.Logo : model.Logo;
competition.BackgroundImage = (string.IsNullOrEmpty(model.BackgroundImage)) ? competition.BackgroundImage : model.BackgroundImage;
competition.ColourScheme = (string.IsNullOrEmpty(model.ColourScheme)) ? competition.ColourScheme : model.ColourScheme;
competition.Current = (model.Current == competition.Current) ? competition.Current : model.Current;

我要做的是检查属性是否已更改。如果有,则取新值,否则不管它。

有人可以帮助我提供更好的解决方案,因为这种情况会发生很多(我有其他类和函数做同样的事情但具有不同的属性)。

我希望来使用图书馆,因为我不喜欢有图书馆,并且当它存在很多情况时会使用它们。

1 个答案:

答案 0 :(得分:0)

难道你不能只创建一个辅助方法吗?不是它很漂亮或有任何错误检查,但这有效:

public static void UpdateValueIfChanged<TData,TValue>(TData data, Expression<Func<TData,TValue>> propFunc, TValue newValue)
{
    var prop = (MemberExpression)propFunc.Body;
    var propInfo = (PropertyInfo)prop.Member;

    Func<TData, TValue> getFunc = propFunc.Compile();
    TValue originalValue = getFunc(data);
    if (!EqualityComparer<TValue>.Default.Equals(originalValue,newValue))
    {
        propInfo.SetMethod.Invoke(data, new object[] { newValue });
    }
}

您可以将其称为UpdateIfChanged(competition c => c.Name, model.Name)