Reputation: 1270
Code:
abstract class Parent{
void changeChild(){
}
}
class Child1: Parent{
}
class Child2: Parent{
}
//-----
Parent parent = new Child1(); //instantiated as Child1
parent.changeChild(); //change type of this class to Child2
so parent should be instance of Child2 class.
I understand that Child1 can be different from Child2(more/less fields, methods), but I just want to call constructor on this object, which is not allowed.
simple
parent = new Child2();
could be done, but there is like 10 child classes(Growing) and I want to move this into parent class
Is this somehow possible in c#?
Thanks
Upvotes: 1
Views: 5387
Reputation: 112402
You cannot do it like this. Perhaps you could create Parent
as a wrapper class
class Parent
{
Parent _child;
public Parent(Parent child)
{
_child = child;
}
public void ChangeChild(Parent child)
{
_child = child;
}
public string AProperty {
get { return _child.AProperty; }
set { _child.AProperty = value; }
}
public int AMethod(int x)
{
return _child.AMethod(x);
}
}
And then
Parent parent = new Parent(new Child1());
parent.AProperty = "hello";
int y = parent.AMethod(55);
parent.ChangeChild(new Child2());
Note: The parent should not have knowledge about the specific children in a good OO-design. This ensures that you can create new children later (say Child3
) without having to change Parent
.
However, if this is not an issue for you and you want the parent to care automatically about changing children then change or overload the constructor with
public Parent()
{
_child = new Child1();
}
and change or overload ChangeChild
with
public void ChangeChild()
{
if (_child is Child1) {
_child = new Child2();
} else {
_child = new Child1();
}
}
Upvotes: 0
Reputation: 700402
You can't change the type of an existing object, but you can create a new object and return it.
Example:
abstract class Parent{
Parent ChangeChild<T>() where T : Parent {
if (typeof(T) == typeof(Child1)) {
return new Child1(this);
if (typeof(T) == typeof(Child2)) {
return new Child2(this);
} else {
throw new NotImplementedException("Unhandled type");
}
}
}
class Child1: Parent{
public Child1() {} // create
public Child1(Parent source) {} // convert
}
class Child2: Parent{
public Child2() {} // create
public Child2(Parent source) {} // convert
}
Parent parent = new Child1();
parent = parent.ChangeChild<Child2>();
Upvotes: 1
Reputation: 236248
If you need to change type of some object in runtime, it's not case for inheritance. You should use composition here. Try something like Strategy (if Parent
class represents some behavior).
public class Foo
{
// provide default value (or inject it via ctor)
private Parent _parent = new Child1();
public void ChangeChild(Parent parent){
_parent = parent;
}
public void Bar()
{
_parent.DoSomething();
}
}
public abstract class Parent
{
public abstract void DoSomething();
}
public class Child1: Parent
{
public override void DoSomething() { ... }
}
public class Child2: Parent
{
public override void DoSomething() { ... }
}
And now you can change type of dependency at runtime:
Foo foo = new Foo(new Child1());
foo.Bar(); // child1 implementation used
foo.ChangeChild(new Child2());
foo.Bar(); // child2 implementation used
Upvotes: 0
Reputation: 62266
Well, if you want just that ctor is called automaticcally, should be enough to wtrite something, like
class Child1: Child2{
}
class Child2: Parent{
}
So you have Child2
ctor that will be called when Child1
is constructed. But it's completely different architecture design in regard if yours.
If it's not somethign you're asking for, please clarify.
Upvotes: 0
Reputation: 17584
Would something like this work?
abstract class Parent {
private Parent Proxy;
public void ChangeChild<T>() where T : Parent, new() {
Proxy = new T();
}
}
You'd have to use the Proxy
object to call members and properties.
Upvotes: 0
Reputation: 190952
Automapper might be your best bet.
T changeChild<T>() : Parent{
// change the type here.
}
Upvotes: 0