Home > Software design >  Copy common properties between objects in c#
Copy common properties between objects in c#

Time:04-29

Given this scenario:

internal class FullLogin
    {
        public string username { get; set; }
        public string password { get; set; }
        public string device { get; set; }
        public string privacy { get; set; }
    }

internal class RegularLogin
    {
        public string username { get; set; }
        public string password { get; set; }
    }

FullLogin fullLogin = new Login() {
     username="abc",
     password="123",
     device = "MyDevice",
     privacy="public"
};
RegularLogin regularLogin= new();
// To archive: regularLogin = all the values of the common properties bw objects
// expected result of regularLogin: username="abc" , password="123"
// so

Anybody know how to achieve it in a short way instead of assigning each property manually?

CodePudding user response:

Define a copy constructor:

internal class RegularLogin
{
    public RegularLogin()
    {
    }
    public RegularLogin(RegularLogin login)
    {
        this.username = login.username;
        this.password = login.password;
    }
    public string username { get; set; }
    public string password { get; set; }
}

Make your FullLogin inherith RegularLogin and also with a copy constructor. Here, base(login) run the user and pass assignements.

internal class FullLogin : RegularLogin
{
    public FullLogin()
    {
    }
    public FullLogin(RegularLogin login)
        : base(login)
    {
    }
    public FullLogin(FullLogin login)
        : base(login)
    {
        this.device = login.device;
        this.privacy = login.privacy;
    }
    public string device { get; set; }
    public string privacy { get; set; }
}

Then you can do this:

FullLogin fullLogin = new FullLogin()
{
    username = "abc",
    password = "123",
    device = "MyDevice",
    privacy = "public"
};
RegularLogin regularLogin = new RegularLogin(fullLogin);
FullLogin fullLogin2 = new FullLogin(regularLogin);

UPDATE

I added another copy contructor to FullLogin that allow you create a FullLogin with the RegularLogin properties.

UPDATE 2

Another way to do is using a CopyTo method. In this way, you can copy between your logins in any moment, not only in the contruction. Also, you need only one CopyTo method, with the base class (RegularLogin) and, in derived classes, you can check if that RegularLogin is also a FullLogin and copy the other properties

internal class RegularLogin
{
    public RegularLogin()
    {
    }
    public RegularLogin(RegularLogin login)
    {
        login.CopyTo(this);
    }
    public string username { get; set; }
    public string password { get; set; }
    public virtual void CopyTo(RegularLogin login)
    {
        login.username = this.username;
        login.password = this.password;
    }
}

internal class FullLogin : RegularLogin
{
    public FullLogin()
    {
    }
    public FullLogin(RegularLogin login)
        : base(login)
    {                
    }
    public string device { get; set; }
    public string privacy { get; set; }
    public override void CopyTo(RegularLogin login)
    {
        base.CopyTo(login);

        FullLogin fullLogin = login as FullLogin;
        if (fullLogin != null)
        {
            this.device = fullLogin.device;
            this.privacy = fullLogin.privacy;
        }
    }
}

Test:

FullLogin fullLogin = new FullLogin()
{
    username = "abc",
    password = "123",
    device = "MyDevice",
    privacy = "public"
};
RegularLogin regularLogin = new RegularLogin(fullLogin);
FullLogin fullLogin2 = new FullLogin(regularLogin);
FullLogin fullLogin3 = new FullLogin(fullLogin);

CodePudding user response:

If you want something generic, that works with all kinds of objects, you could try reflection, e.g. something like this:

static void CopyPropertyValues(object source, object target)
{
    var sourceProps = source.GetType().GetProperties();
    var targetProps = target.GetType().GetProperties();

    foreach (var sourceProp in sourceProps)
    {
        foreach (var targetProp in targetProps)
        {
            if (sourceProp.Name == targetProp.Name && sourceProp.PropertyType == targetProp.PropertyType)
            {
                targetProp.SetValue(target, sourceProp.GetValue(source));
                break;
            }
        }
    }
}       

Error handling etc. should be put in for production use, of course.

  •  Tags:  
  • c#
  • Related