Inject a base instance into a downcast class in C #

Suppose I have two classes:

class Employee 

and

 class AdvancedEmployee:Employee 

I know something like this will not work, since I cannot omit in C #:

 var employee = new Employee(); var advanced = employee as AdvancedEmployee; 

My question is: how to make downcast efficiently? Actually, I have a constructor in AdvancedEmployee that takes an Employee parameter as a parameter and uses it to enter its values, basically making a clone.


Update

To allow duplication of data, I slightly changed the approach, and now AdvancedEmployee CONTAINS an employee, not himself. Example:

 class Employee; class AdvancedEmployee { private employee public AdvancedEmployee(Employee employee){ this.employee = employee } } 
+8
c # downcast
source share
5 answers

Create an interface. And since you cannot change Employee, create an adapter that you have:

 class EmployeeAdapter : IEmployee { private Employee emp; public EmployeeAdapter(Employee emp) { this.emp = emp; } public int SomeMethodInEmployee() { return emp.SomeMethodInEmployee(); } } class AdvancedEmployee : IEmployee { } 
+4
source share

It can’t be the cast, it’s actually a conversion between different types.

I would add ctor or a static member function, such as AdvancedEmployee FromBase(Employee e) , to create a derived type from this base type.

+3
source share

Creating a new object is the most readable and clear way. You can also define explicit or implicit type conversion operators in your Employee class.

 public static explicit operator AdvancedEmployee(Employee e) { return new AdvancedEmployee(e); } 

And then use it like this:

 var e = new Employee(); var ae = (AdvancedEmployee) e; 
+2
source share

This is how I dealt with this in the past, which I thought was cool ... if all the data elements in Employee and AdvancedEmployee are properties, then you can use reflection to copy data values ​​from the base class to the derived class. You can then work with the derived class as if it were originally printed in this way, without having to encapsulate the base class.

 public class Employee { public int ID { get; set; } public string Foo { get; set; } public void SomeMethod() { } } public class AdvancedEmployee : Employee { public string Bar { get; set; } public void SomeAdvMethod() { } } Employee emp = new Employee() { ID = 5, Foo = "Hello" }; // To create a AdvancedEmployee from emp AdvancedEmployee advEmp = new AdvancedEmployee() { Bar = "A prop not in Emp that might need a value" } foreach (var p in typeof(Employee).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.CanWrite)) typeof(AdvancedEmployee).GetProperty(p.Name).SetValue(advEmp, p.GetValue(emp)); 
+2
source share

as in C # checks the type of execution. That is, if the test object is really not an AdvancedEmployee , you cannot magically transform Employee into AdvancedEmployee . Therefore, if you need AdvancedEmployee , you need to build it somehow.

Depending on what you are going to achieve, there are different approaches. Perhaps you can do with the constructor AdvancedEmployee(Employee proto) , which will copy the necessary values ​​from proto ? Or maybe you need to wrap an existing Employee with AdvancedEmployee .

Please note that you may need to replace the code with the newly created AdvancedEmployee in the code in which the old employee is stored.

The transition method (with some Java flavor) may be to create an Employee factory, which will create an AdvancedEmployee if necessary. Then you need to do all the code with factory instead of creating Employee with new . This scenario, however, will not help if you still need to change the type of execution.

+1
source share

All Articles