Super-E-
Super-E-

Reputation: 78

Update arbitrary member with only non null values

I have two classes with no inheritance relationship (well, excepting being Object):

class A
{
  Member1 m1;
  Member2 m2;
}

class B
{
  Member1 m3;
  Member2 m4;
}

Each member of a class is paierd with a member of the same arbitrary type in the other class, it might or might not have the same name, it can be null. I would like to do something like this:

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

just to update values that are not null, where a is an instance of class A and b is an instance of class B. The number of members to update might grow with time, I'd like some more general and elegant way to do the update, something to be used like this:

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

I have tried with an extension method:

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

but there is clearly something wrong because I get an exception saying that the left-hand side of the the equality key(source) must be a variable. Any ideas?

Upvotes: 1

Views: 68

Answers (2)

Hogan
Hogan

Reputation: 70523

You could do something like this

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

Then your code is very simple:

a.Setm1(b.m3);

Or you could use the accessor (with the same code) and you would have

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

a.Setm1 = b.m3;

Upvotes: 0

juharr
juharr

Reputation: 32276

The reason this doesn't work is because a Func is literally a function that returns a value. When called you have to assign that value to a variable, thus the error message you are getting. Instead of a Func you could use an Action and pass both the source and the key to it.

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

Then call it like this.

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

But really it would be simpler to just do the following

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

That will assign b.m3 to a.m1 if it is not null. Otherwise it just assigns a.m1 to itself.

Although for this specific case you should look into mapping libraries that can handle this type of thing for you.

Upvotes: 1

Related Questions