私はC#(および[〜#〜] oop [〜#〜])。次のようなコードがある場合:
class Employee
{
// some code
}
class Manager : Employee
{
//some code
}
質問1:これを行う他のコードがある場合:
Manager mgr = new Manager();
Employee emp = (Employee)mgr;
ここでEmployee
はManager
ですが、そのようにEmployee
にキャストすると、アップキャストしていることになりますか?
質問2:
複数のEmployee
クラスオブジェクトがあり、それらのすべてではないが一部がManager
である場合、可能な限りそれらをダウンキャストできますか?
それは正しいです。それをすると、それをemployee
オブジェクトにキャストするので、マネージャー固有のものにはアクセスできません。
ダウンキャスティングは、基本クラスを取得し、それをより具体的なクラスに変換することを試みます。これは、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
}
不明な点がある場合は、修正させていただきます。
アップキャスティング((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");
あなたの場合
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
警告:アップキャストを行うと、スーパークラスのメソッド、プロパティなどにのみアクセスできます...
各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..
}
回答1:はい、アップキャストと呼ばれていますが、その方法は現代的な方法ではありません。アップキャストは、変換を必要としない暗黙的に実行できます。したがって、Employee emp = mgr;と書くだけでアップキャストに十分です。
回答2:マネージャークラスのオブジェクトを作成する場合、マネージャーは従業員であると言えます。なぜならclass Manager:EmployeeはIs-A関係を従業員クラスとManagerクラスの間で表しているからです。したがって、すべてのマネージャーは従業員であると言えます。
しかし、Employeeクラスのオブジェクトを作成する場合、この従業員がマネージャーであるとは言えません。これは、class Employeeが他のクラスを継承しないクラスだからです。そのため、そのEmployee ClassオブジェクトをManager Classオブジェクトに直接ダウンキャストすることはできません。
したがって、答えは、Employee ClassオブジェクトからManager Classオブジェクトにダウンキャストする場合、最初にManagerクラスのオブジェクトが必要です。次に、それをアップキャストしてからダウンキャストできます。