web-dev-qa-db-ja.com

ダウンキャストとアップキャスト

私はC#(および[〜#〜] oop [〜#〜])。次のようなコードがある場合:

class Employee
{
    // some code
}


class Manager : Employee
{
    //some code
}

質問1:これを行う他のコードがある場合:

   Manager mgr = new Manager();
   Employee emp = (Employee)mgr;

ここでEmployeeManagerですが、そのようにEmployeeにキャストすると、アップキャストしていることになりますか?

質問2

複数のEmployeeクラスオブジェクトがあり、それらのすべてではないが一部がManagerである場合、可能な限りそれらをダウンキャストできますか?

80
user184805
  1. それは正しいです。それをすると、それをemployeeオブジェクトにキャストするので、マネージャー固有のものにはアクセスできません。

  2. ダウンキャスティングは、基本クラスを取得し、それをより具体的なクラスに変換することを試みます。これは、isと次のような明示的なキャストを使用して実現できます。

    if (employee is Manager)
    {
        Manager m = (Manager)employee;
        //do something with it
    }
    

または、次のようなas演算子を使用します。

Manager m = (employee as Manager);
if (m != null)
{
    //do something with it
}

不明な点がある場合は、修正させていただきます。

82
RCIX

アップキャスティング(Employee)someInstanceを使用)は、一般に、型が別の型から派生している場合にコンパイラがコンパイル時に通知できるため簡単です。

ダウンキャスティングただし、コンパイラは、問題のインスタンスが指定されたタイプであるかどうかを常に把握しているとは限らないため、一般的に実行時に実行する必要があります。 C#には、このための2つの演算子があります。-isは、ダウンキャストが機能するかどうかを示し、true/falseを返します。 asキャストを試行し、可能な場合は正しい型を返し、そうでない場合はnullを返します。

従業員がマネージャーかどうかをテストするには:

Employee m = new Manager();
Employee e = new Employee();

if(m is Manager) Console.WriteLine("m is a manager");
if(e is Manager) Console.WriteLine("e is a manager");

これも使用できます

Employee someEmployee = e  as Manager;
    if(someEmployee  != null) Console.WriteLine("someEmployee (e) is a manager");

Employee someEmployee = m  as Manager;
    if(someEmployee  != null) Console.WriteLine("someEmployee (m) is a manager");
47
Preet Sangha
  • pcastingは、サブクラス参照から基本クラス参照を作成する操作です。 (サブクラス->スーパークラス)(つまり、マネージャー->従業員)
  • ダウンキャスティングは、基本クラス参照からサブクラス参照を作成する操作です。 (スーパークラス->サブクラス)(つまり、従業員->マネージャー)

あなたの場合

Employee emp = (Employee)mgr; //mgr is Manager

あなたはアップキャスティングをしています。

アップキャストは、実行時に失敗する可能性があるため、明示的なキャストを必要とするダウンキャストとは異なり、常に成功します。(InvalidCastException)。

C#には、この例外がスローされるのを回避するための2つの演算子があります。

から始まる:

Employee e = new Employee();

最初:

Manager m = e as Manager; // if downcast fails m is null; no exception thrown

第二:

if (e is Manager){...} // the predicate is false if the downcast is not possible 

警告:アップキャストを行うと、スーパークラスのメソッド、プロパティなどにのみアクセスできます...

9
overcomer

各EmployeeオブジェクトをManagerオブジェクトであるかどうかを確認する必要がある場合は、OfTypeメソッドを使用します。

List<Employee> employees = new List<Employee>();

//Code to add some Employee or Manager objects..

var onlyManagers = employees.OfType<Manager>();

foreach (Manager m in onlyManagers) {
  // Do Manager specific thing..
}
6
HOKBONG

回答1:はい、アップキャストと呼ばれていますが、その方法は現代的な方法ではありません。アップキャストは、変換を必要としない暗黙的に実行できます。したがって、Employee emp = mgr;と書くだけでアップキャストに十分です。

回答2:マネージャークラスのオブジェクトを作成する場合、マネージャーは従業員であると言えます。なぜならclass Manager:EmployeeIs-A関係を従業員クラスとManagerクラスの間で表しているからです。したがって、すべてのマネージャーは従業員であると言えます。

しかし、Employeeクラスのオブジェクトを作成する場合、この従業員がマネージャーであるとは言えません。これは、class Employeeが他のクラスを継承しないクラスだからです。そのため、そのEmployee ClassオブジェクトをManager Classオブジェクトに直接ダウンキャストすることはできません。

したがって、答えは、Employee ClassオブジェクトからManager Classオブジェクトにダウンキャストする場合、最初にManagerクラスのオブジェクトが必要です。次に、それをアップキャストしてからダウンキャストできます。

0
Asad Patel