仅使用非空值更新任意成员

时间:2014-12-19 18:09:02

标签: c# .net lambda

我有两个没有继承关系的类(好吧,除了是Object):

class A
{
  Member1 m1;
  Member2 m2;
}

class B
{
  Member1 m3;
  Member2 m4;
}

一个类的每个成员都与另一个类中相同任意类型的成员相对应,它可能具有相同的名称,也可能不具有相同的名称,它可以为null。 我想做这样的事情:

 if (b.m3 != null) a.m1 = b.m3;

仅更新非空值,其中a是类A的实例,b是类B的实例。 要更新的成员数量可能会随着时间的推移而增长,我想要一些更通用和更优雅的方式来进行更新,这样可以使用:

a.Update(d => d.m1, b.m3)

我尝试过使用扩展方法:

public static void Update<TSource, TKey>(this TSource source, Func<TSource, TKey> key, TKey newValue)
 where TSource : A
{
 if (newValue != null)
 {
  key(source) = newValue;
 }
}

但显然有一些错误,因为我得到一个例外,即等于key(source)的左侧必须是变量。 有什么想法吗?

2 个答案:

答案 0 :(得分:1)

这不起作用的原因是因为Func实际上是一个返回值的函数。调用时,您必须将该值赋给变量,从而得到错误消息。您可以使用Func代替Action,并将源和密钥传递给它。

public static void Update<TSource, TKey>(
    this TSource source, 
    Action<TSource, TKey> action, 
    TKey newValue)
 where TSource : A
{
     if (newValue != null)
     {
        action(source, newValue);
     }
}

然后这样称呼它。

a.Update((myA, val) => myA.m1 = val, b.m3);

但实际上,执行以下操作会更简单

a.m1 = b.m3 ?? a.m1;

如果b.m3不是a.m1,则会将null分配给a.m1。否则它只会将{{1}}分配给自己。

虽然对于这种特殊情况,你应该研究能够为你处理这类事情的映射库。

答案 1 :(得分:0)

你可以做这样的事情

Member1 m1;
public Setm1(Member1 in)
{
  if (in != null) m1 = in;
}

然后你的代码非常简单:

a.Setm1(b.m3);

或者你可以使用访问者(使用相同的代码),你可以使用

public Member1 Setm1
{
   set {  if (value != null) m1 = value;
}

a.Setm1 = b.m3;