Reputation: 78
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
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
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