0
public class SomePropertyClass{
    public string VarA{get;set;}
    public string VarB{get;set;}
}

SomePropertyClass v1 = new SomePropertyClass(){VarA = "item 1"};
SomePropertyClass v2 = new SomePropertyClass(){VarB = "item 2"};

Is it possible to create a third variable that will have:

v3: VarA = "item 1",VarB = "item 2"

I mean, I want to merge objects with linq to object.

Edit
for now i need from the same type. but it would be nice in the future to merge by property name.

I have an account model with a lot of properties that the user input in step 1.
I want to merge this half full model with step 2 half full model.

Edit 2

//step 1
        GlobalOnBoardingDataModel step1= (GlobalOnBoardingDataModel)HttpContext.Current.Session[SessionVariableNameStepOne];
//step 2           
        GlobalOnBoardingDataModel step2 = (GlobalOnBoardingDataModel)HttpContext.Current.Session[SessionVariableNameStepTwo];



     class GlobalOnBoardingDataModel {
        public string Email;//step 1
        public string Name;//step 1
        public string Phone;//step2
        public string Address;//step2
        }
    }

thanks

5
  • 3
    var v3 = new SomePropertyClass { VarA = v1.VarA, VarB = v2.VarB }; ? Why would you want to use LINQ ? Commented Jan 26, 2012 at 8:18
  • Help us understand more about your use case. Will you always have exactly two objects, one with VarA set and one with VarB set? Commented Jan 26, 2012 at 8:19
  • Then please give us a full example! Commented Jan 26, 2012 at 8:25
  • Are you sure this is a good idea? It looks like you would be much better off by simply storing 1 object in the session, and write to one subset of the properties during "step1" and another subset during "step2". Commented Jan 26, 2012 at 8:38
  • @JonasH, MVC is de-serializing it, it means that I need to join them, I cannot tell mvc to de-serialize over an existing object. Commented Jan 26, 2012 at 8:41

3 Answers 3

9

Here's the answer to the OP's question which is:

  • an exact answer
  • for two objects of the same type
    • (for two objects of different types the code would be almost identical)
  • a solution that is not hard coded
  • using linq
  • that respects non-nullity of source values
  • that doesn't need an external library
  • in one line of code.
public static T Merge<T>(T target, T source)
{
  typeof(T)
  .GetProperties()
  .Select((PropertyInfo x) => new KeyValuePair<PropertyInfo, object>(x, x.GetValue(source, null)))
  .Where((KeyValuePair<PropertyInfo, object> x) => x.Value != null).ToList()
  .ForEach((KeyValuePair<PropertyInfo, object> x) => x.Key.SetValue(target, x.Value, null));

  //return the modified copy of Target
  return target;
}
Sign up to request clarification or add additional context in comments.

1 Comment

@A1rPun, I guess return target; is a line of code. So, one pretty line of code ಠ‿ಠ
3

Here's a way to accomplish this using reflection:

public class SomePropertyClass
{
    public string VarA { get; set; }
    public string VarB { get; set; }
}

static class Program
{
    static void Main(string[] args)
    {
        SomePropertyClass v1 = new SomePropertyClass() { VarA = "item 1" };
        SomePropertyClass v2 = new SomePropertyClass() { VarB = "item 2" };

        var yo = v1.Combine(v2);
    }

    static public IEnumerable<object> Combine<T, U>(this T one, U two)
    {
        var properties1 = one.GetType().GetProperties().Where(p => p.CanRead && p.GetValue(one, null) != null).Select(p => p.GetValue(one, null));
        var properties2 = two.GetType().GetProperties().Where(p => p.CanRead && p.GetValue(two, null) != null).Select(p => p.GetValue(two, null));

        return new List<object>(properties1.Concat(properties2));
    }
}

1 Comment

Changed answer to use reflection in order to provided an auto mechanism.
3

Do you mean something like this ... a Merge method that takes whichever value is not null from the matching properties?

public class SomePropertyClass{
    public string VarA{get;set;}
    public string VarB{get;set;}

    public SomePropertyClass Merge (SomePropertyClass other)
    {
       return new SomePropertyClass 
                    { VarA = this.VarA ?? other.VarA, 
                      VarB = this.VarB ?? other.VarB 
                    };
    }

If you wanted a solution that would work for any class you'd need to use reflection to find all the properties and then copy the missing ones. }

2 Comments

So there is no other cleaver auto-something that merge it? (-: ?
Not built in, you'll need to use reflection or some library like valueinjecter.codeplex.com

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.