8

2 つのクラスがあるとします。

class Employee 

class AdvancedEmployee:Employee

C# ではダウンキャストできないため、次のようなものが機能しないことはわかっています。

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

私の質問は次のとおりです。効率的な方法でダウンキャストを達成するにはどうすればよいですか? 実際には、従業員をパラメーターとして受け取り、それを使用してその値を注入し、基本的にクローンを作成するコンストラクターが AdvancedEmployee にあります。


アップデート

重複するデータを解決するために、アプローチを少し変更し、AdvancedEmployee CONTAINS は従業員そのものではなく、従業員を含むようになりました。例:

class Employee;

class AdvancedEmployee
{
   private employee

   public AdvancedEmployee(Employee employee){

    this.employee = employee

  }           

}
4

5 に答える 5

5

インターフェイスを作成します。Employee を変更することはできないため、所有するアダプターを作成します。

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

class AdvancedEmployee : IEmployee { } 
于 2012-04-16T11:10:15.963 に答える
5

キャストすることはできません。実際には、異なる型間の変換です。

のような ctor または静的メンバー関数を追加して、特定の基本型から派生型AdvancedEmployee FromBase(Employee e)構築します。

于 2012-04-16T10:57:43.600 に答える
3

これは私が過去にそれを処理した方法で、ちょっとクールだと思いました... Employee と AdvancedEmployee のすべてのデータ要素がプロパティである場合、リフレクションを使用してデータ値を基本クラスから派生クラスにコピーできます. 次に、基本クラスをカプセル化する必要なく、派生クラスを最初にそのように入力したかのように操作できます。

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));
于 2016-04-20T19:58:33.413 に答える
2

新しいオブジェクトを作成するのが、最も読みやすく明確な方法です。Employee クラスで明示的または暗黙的な型変換演算子を定義することもできます。

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

そして、次のように使用します。

var e = new Employee();
var ae = (AdvancedEmployee) e;
于 2012-04-16T10:59:16.897 に答える
1

asC# では、ランタイム タイプがチェックされます。つまり、テスト対象のオブジェクトが実際に ではない場合、AdvancedEmployee魔法のように に変換することはありませEmployeeAdvancedEmployee。したがって、 が必要な場合はAdvancedEmployee、何らかの形で自分で構築する必要があります。

何を達成するかによって、さまざまなアプローチがあります。おそらくAdvancedEmployee(Employee proto)、必要な値をproto?からコピーするコンストラクターを使用して行うことができます。Employeeまたは、既存のものを でラップする必要があるかもしれませんAdvancedEmployee

古い従業員を格納するコードを、新しく作成しAdvancedEmployeeた .

Employee必要に応じて を作成するファクトリを作成するのが (Java のテイストを伴う) 方法かもしれませんAdvancedEmployeeEmployee次に、 withを作成する代わりに、すべてのコードで factory を使用する必要がありますnew。ただし、ランタイム タイプを変更する必要がある場合、このシナリオは役に立ちません。

于 2012-04-16T10:58:02.053 に答える