簡體   English   中英

在C#中將基類實例轉換為派生類(向下轉換)

[英]Cast base instance to derived class (downcast) in C#

假設我有兩個類:

class Employee 

class AdvancedEmployee:Employee

我知道這樣的事情不會起作用,因為我不能低估C#:

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

我的問題是:如何以有效的方式完成垂頭喪氣? 實際上我在AdvancedEmployee上有一個構造函數,它將Employee作為參數並使用它來注入它的值,基本上是克隆。


更新

為了解決可能重復的數據,我改變了方法,現在AdvancedEmployee包含了一個員工而不是一個員工。 例:

class Employee;

class AdvancedEmployee
{
   private employee

   public AdvancedEmployee(Employee employee){

    this.employee = employee

  }           

}

創建一個界面。 由於您無法修改Employee,請創建您擁有的適配器

class EmployeeAdapter : IEmployee
{
    private Employee emp;
    public EmployeeAdapter(Employee emp) { this.emp = emp; }
    public int SomeMethodInEmployee() { return emp.SomeMethodInEmployee(); }
}

class AdvancedEmployee : IEmployee { } 

它不能是演員 ,它實際上是不同類型之間的轉換

我會添加一個ctor或靜態成員函數,如AdvancedEmployee FromBase(Employee e) ,從給定的基類型構造派生類型。

這是我過去處理它的一種方式,我認為它有點酷......如果Employee和AdvancedEmployee中的所有數據元素都是Properties,那么你可以使用反射將數據值從基類復制到派生類中。 然后,您可以使用派生類,就好像他最初以這種方式鍵入,而無需封裝基類。

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));

創建新對象是最可讀和最清晰的方式。 您還可以在Employee類中定義顯式或隱式類型轉換運算符。

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

然后像這樣使用它:

var e = new Employee();
var ae = (AdvancedEmployee) e;

as在C#中檢查運行時類型一樣 也就是說,如果被測試的對象確實不是AdvancedEmployee ,那么你就不會讓它神奇地將Employee轉換為AdvancedEmployee 因此,如果您需要AdvancedEmployee ,您需要以某種方式自己構建它。

根據您要實現的目標,有不同的方法。 也許您可以使用構造函數AdvancedEmployee(Employee proto) ,它將從proto復制所需的值? 或者您可能需要使用AdvancedEmployee包裝現有Employee

請注意,您可能需要讓存儲舊員工的代碼將其替換為新創建的AdvancedEmployee

一種方法(具有一些Java品味)可能是創建一個Employee工廠,如果需要,它將創建一個AdvancedEmployee 然后,您需要使所有代碼使用工廠而不是使用new創建Employee 但是,如果您仍需要更改運行時類型,則此方案無濟於事。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM