Irshu
Irshu

Reputation: 8436

Is there a jQuery extend in c#?

 var _Contact = new ContactLstModel { 
             ContactName="xxxxxx",
              EmailAddr="yyyyyy",
               ContactNo="ddddddd",
               SelectedContactType="dddd"
            };

 var _ContactOption= new ContactLstModel{
                 ContactType= new List<SelectListItem>(){
                 new SelectListItem{
                  Text="sss",Value="ddd"
                 }
                 }
            };

as you can see both are of the same model ContactLstModel. Now how do I combine both into one?

Like in jQuery, we have $.extend(dest,source);

Is there an equivalent in C#?

Upvotes: 5

Views: 1683

Answers (3)

Faris Zacina
Faris Zacina

Reputation: 14274

There is not a built-in equivalent of $.extend in C# and .NET 4.5.

However you can find many examples of people trying to achieve that kind of behavior using reflection in .NET. There are others who use serialization (JSON.NET etc.) to achieve similar behaviors . Another approach would be to use IOC containers like Automapper.

Here is an example how to merge your first object into the second object using Automapper IOC:

var expr = Mapper.CreateMap<ContactLstModel, ContactLstModel>().ForMember("ContactType", (conf) => { conf.Ignore(); });
var merged = Mapper.Map<ContactLstModel, ContactLstModel>(_Contact, _ContactOption);

With Automapper you can control how to map each single property from source to destination.

If you don't want external library dependencies, and want full control you can use a pure Reflection approach.

For example you could use something similar as the CopyValues method from this link and merge the second object properties with the first one using reflection.

CopyValues<ContactLstModel>(_Contact, _ContactOption);

So this line of code will copy the ContactType property values from the second object into the first one.

CopyValues uses reflection to loop through the properties of the objects:

public static void CopyValues<T>(T target, T source)
{
    Type t = typeof(T);

    var properties = t.GetProperties().Where(prop => prop.CanRead && prop.CanWrite);

    foreach (var prop in properties)
    {
        var value = prop.GetValue(source, null);
        if (value != null)
            prop.SetValue(target, value, null);
    }
}

Of course this does not support everything jquery extend does (merging, shallow and deep cloning into a new object etc.), but it can satisfy your current needs. You can extend on these principles and build a more comprehensive solution.

However have in mind that C# is not a language like Javascript, and the cost of doing reflection is much higher in C#, while in Javascript the properties of a prototype can be listed with a cheap for-in iteration, or with a call to Object.keys().

Upvotes: 6

Tomas Aschan
Tomas Aschan

Reputation: 60564

You could do it with an extension method:

public static class ContactModelExtensions {
    public static ContactModel Extend(this ContactModel first, ContactModel replacement) {
        if (!replacement.ContactsName.IsNullOrEmpty()) // or whatever criteria you want
        {
            first.ContactsName = replacement.ContactsName;
        }
        // similar assignment for all other properties

        return first; // since we return the first one, properties not set in override
                      // will be untouched
    }
}

Now, you can just

var extendedContact = _Contact.Extend(_ContactOptions);

to get it done.

Upvotes: 3

IVAAAN123
IVAAAN123

Reputation: 567

You can use some frameworks for do it. For example with ValueInjecter:

    public class NoNullsInjection : ConventionInjection
    {
        protected override bool Match(ConventionInfo c)
        {
            return c.SourceProp.Name == c.TargetProp.Name
                    && c.SourceProp.Value != null;
        }
    }

    class A
    {
        public string a { get; set; }
        public string b { get; set; }
    }

    static void Main(string[] args)
    {
        A a1 = new A() { a = "123" };
        A a2 = new A() { b = "456" };
        A c = new A();

        c.InjectFrom(new NoNullsInjection(),a1,a2); 
        // "c" now have a="123", b="456"     

    }

Upvotes: 2

Related Questions