KOGI
KOGI

Reputation: 3989

How to initialize an object from another object

I've been programming for 15 years, but I'm new to C# and inexperienced with strongly typed languages in general, so I apologize if this is a super-noob question.

I'm trying to avoid a fair amount of repetitive code and am having trouble figuring out a way to do what I want. Here's an example of what I currently have:

class BaseModel {
    string sharedProperty1;
    string sharedProperty2;
    string sharedProperty3;
    string sharedProperty4;
    string sharedProperty5;
    string sharedProperty6;
}

class ExtendedModelA : BaseModel {
    string exclusivePropertyA;
}

class ExtendedModelB : BaseModel {
    string exclusivePropertyB;
}

// --------

dynamic finalModel;
if( conditionA )
{
    finalModel = new ExtendedModelA{
        sharedProperty1 = 1,
        sharedProperty2 = 2,
        sharedProperty3 = 3,
        sharedProperty4 = 4,
        sharedProperty5 = 5,
        sharedProperty6 = 6,
        exclusivePropertyA = "foo"
    };
}
else
{
    finalModel = new ExtendedModelB{
        sharedProperty1 = 1,
        sharedProperty2 = 2,
        sharedProperty3 = 3,
        sharedProperty4 = 4,
        sharedProperty5 = 5,
        sharedProperty6 = 6,
        exclusivePropertyB = "bar"
    };
}

As you can see, there is a lot of redundancy since the only difference in initialized values is the last exclusiveProperty on each (in my specific case, I have about 30 properties being duplicated in each half of the if/else and only 2 or 3 unique). What I'd like to do is initialize a "template" model just once with all the sharedProperty values, and inside the if/else only need to initialize the exclusiveProperty values.

Here's some psuedo-code to illustrate the concept of what I'd like to do, but I haven't been able to make it work, yet.

var template = new BaseModel
{
    sharedProperty1 = 1,
    sharedProperty2 = 2,
    sharedProperty3 = 3,
    sharedProperty4 = 4,
    sharedProperty5 = 5,
    sharedProperty6 = 6
};

dynamic finalModel;
if( conditionA )
{
    finalModel = new ExtendedModelA{template};
    finalModel.exclusivePropertyA = "foo";
}
else
{
    finalModel = new ExtendedModelB{template};
    finalModel.exclusivePropertyB = "foo";
}

I'm familiar with the factory pattern that could be used to accept the "template" and an "extension" as arguments, but that would be just as much code as simply keeping my duplications, so I'm looking for a more... direct? way to do this.

Upvotes: 2

Views: 852

Answers (2)

Dave Greilach
Dave Greilach

Reputation: 895

I think the simplest way you could do this without repeating code would be to create your object in the if else block with the unique properties, then at the end assign all the shared ones. This would prevent you from having to repeat code.

BaseModel finalModel = null;
if (conditionA)
{
    finalModel = new ExtendedModelA()
                     {
                         exclusivePropertyA = "some value";
                     };
}
else
{
    finalModel = new ExtendedModelB()
                     {
                         exclusivePropertyB = "some other value";
                     };
}
finalModel.sharedProperty1 = "asdf";
// assign the rest of the values

You could also have a constructor for the base model that takes a base model as a parameter and assigns all the values to the new object. This would basically be using the original as a template to create the new. Then you could create the extended classes with the template and pass it to the base constructor.

    class BaseModel
    {
        public string sharedProperty1 { get; set; }
        public string sharedProperty2 { get; set; }
        public string sharedProperty3 { get; set; }
        public string sharedProperty4 { get; set; }
        public string sharedProperty5 { get; set; }
        public string sharedProperty6 { get; set; }

        public BaseModel(BaseModel t)
        {
            //assign template properties 
        }

        public BaseModel()
        {

        }
    }


    class ExtendedModelA : BaseModel
    {
        public string exclusivePropertyA { get; set; }

        public ExtendedModelA(BaseModel t)
            : base(t)
        {

        }
    }

    class ExtendedModelB : BaseModel
    {
        public string exclusivePropertyB { get; set; }

        public ExtendedModelB(BaseModel t)
            : base(t)
        {

        }
    }

Then to use it would be

BaseModel template = new BaseModel()
                         {
                             //assign values
                         };

ExtendedModelA = new ExtendedModelA(template)
                     {
                         exlusivePropertyA = "asdf";
                     };

Upvotes: 2

GreatAndPowerfulOz
GreatAndPowerfulOz

Reputation: 1775

Your second try is almost right. You just need to add a BaseModel ctor to ExtendedModelA & ExtendedModelB:

class ExtendedModelA : BaseModel
{
    public ExtendedModelA(BaseModel b)
        : base(b)
    {
    }
}

then call it like this:

BaseModel template = new BaseModel
{
    // init code
};

finalModel = new ExtendedModelA(template); // note the parenthesis's not curly braces

Upvotes: 1

Related Questions