gpt4 book ai didi

c# - 在不复制代码的情况下将这些更改应用于对象的最佳方法是什么?

转载 作者:太空宇宙 更新时间:2023-11-03 11:05:51 25 4
gpt4 key购买 nike

我正在尝试从另一个对象更新一个对象的多个属性,结果我一遍又一遍地重复相同的代码(我正在展示一个包含 Name 和 LastName 的示例,但我还有 15 个具有类似代码的其他属性)。

重要的是要注意它不是所有属性,所以我不能盲目地复制所有内容。

 public class Person
{

public bool UpdateFrom(Person otherPerson)
{

if (!String.IsNullOrEmpty(otherPerson.Name))
{
if (Name!= otherPerson.Name)
{
change = true;
Name = otherPerson.Name;
}
}

if (!String.IsNullOrEmpty(otherPerson.LastName))
{
if (LastName!= otherPerson.LastName)
{
change = true;
LastName = otherPerson.LastName;
}
}

return change;
}
}

有没有更优雅的方式来编写这段代码?

最佳答案

您可以使用 Expression 来定义您想要访问的字段,处理更新的代码如下所示:-

   Person one = new Person {FirstName = "First", LastName = ""};
Person two = new Person {FirstName = "", LastName = "Last"};
Person three = new Person ();

bool changed = false;
changed = SetIfNotNull(three, one, p => p.FirstName) || changed;
changed = SetIfNotNull(three, one, p => p.LastName) || changed;
changed = SetIfNotNull(three, two, p => p.FirstName) || changed;
changed = SetIfNotNull(three, two, p => p.LastName) || changed;

请注意,|| 表达式中的顺序很重要,因为 .NET 会尽可能缩短求值。或者正如 Ben 在下面的评论中所建议的那样,使用 changed |= ... 作为更简单的替代方法。

SetIfNotNull 方法依赖于另一个方法,该方法执行一些 Expression 魔法将 getter 转换为 setter。

    /// <summary>
/// Convert a lambda expression for a getter into a setter
/// </summary>
public static Action<T, U> GetSetter<T, U>(Expression<Func<T, U>> expression)
{
var memberExpression = (MemberExpression)expression.Body;
var property = (PropertyInfo)memberExpression.Member;
var setMethod = property.GetSetMethod();

var parameterT = Expression.Parameter(typeof(T), "x");
var parameterU = Expression.Parameter(typeof(U), "y");

var newExpression =
Expression.Lambda<Action<T, U>>(
Expression.Call(parameterT, setMethod, parameterU),
parameterT,
parameterU
);

return newExpression.Compile();
}


public static bool SetIfNotNull<T> (T destination, T source,
Expression<Func<T, string>> getter)
{
string value = getter.Compile()(source);
if (!string.IsNullOrEmpty(value))
{
GetSetter(getter)(destination, value);
return true;
}
else
{
return false;
}
}

关于c# - 在不复制代码的情况下将这些更改应用于对象的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15854014/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com