Reputation: 8477
Is there a way to transform a base class into its derived class?
Here is a simple example of two classes:
namespace BLL
{
public class Contact
{
public int ContactID { get; set; }
public string Name { get; set; }
public Contact(){}
}
}
namespace BLL
{
public class SpecialContact : Contact
{
public SpecialContact(){}
}
}
Ideally, I could do something like this:
Contact contact = new Contact();
SpecialContact specialContact = new SpecialContact();
contact.ContactID = 123;
contact.Name = "Jeff";
specialContact = contact;
This code of course throws an error. Apart from writing another constructor for SpecialContact or method that sets each property, is there any other solution?
Upvotes: 3
Views: 591
Reputation: 273784
Outside of writing another constructor for SpecialContact or method that sets each property, is there another solution?
No, not really.
You can automate it with Reflection, but that's about it.
But do note that with a proper design this should almost never be called for. It is not a normal use of (derived) classes.
If Contracts can change into SpecialContracts over time then you either create a new object or model it with a ContactType property and maybe some composition.
Upvotes: 2
Reputation: 161002
If you are just interested in copying properties from one class instance to another (regardless of the relationship of these classes) you can use a mapping tool like AutoMapper.
Your specific example would look like this:
Mapper.CreateMap<Contact, SpecialContact>();
Contact contact = new Contact();
contact.ContactID = 123;
contact.Name = "Jeff";
SpecialContact specialContact = Mapper.Map<Contact, SpecialContact>(contact);
Upvotes: 3
Reputation: 11552
It is illegal to assign Base
class reference to the Derived
class reference variable.
Variable of type X
can only be a reference to an object of type X
or derived.
You probably need to have another instance of SpecialContact
which contains the same data as existing object. There is no way to avoid manual copying.
I use the following extension method when I need to copy the matching properties from one object to another incompatible one(1):
public static void AssignFrom(this object destination, object source) {
Type dest_type = destination.GetType();
Type source_type = source.GetType();
var matching_props = from d in dest_type.GetProperties()
join s in source_type.GetProperties()
on d.Name equals s.Name
where d.IsWritable() && s.IsReadable()
select new {
source = s,
destination = d
};
foreach (var prop in matching_props) {
prop.destination.SetValue(destination, prop.source.GetValue(source, null), null);
}
}
Then you can do:
specialContact.assignFrom(contact);
Please consider this a workaround. The proper solution would be to design properly your class hierarchy where you do not come to this problem.
1 Note: it matches the properties by name and assumes they are of the same type.
Upvotes: 3
Reputation: 727047
Apart from re-considering your inheritance hierarchy that forces you to do this somewhat un-orthodox operation, you have several solutions, all requiring some coding.
As far as transforming your inheritance hierarchy goes, you could use the Decorator Design Pattern to add special functionality to your Contact
class, giving it functionality of a SpecialContact
without subclassing.
Upvotes: 1
Reputation: 1039438
This code of course throws an error. Outside of writing another constructor for SpecialContact or method that sets each property, is there another solution?
No, there's no other way. Reflection might help you if you want to avoid doing all the manual copying.
Upvotes: 1