質問
私は初めてです C# (と OOP)。次のようなコードがある場合:
class Employee
{
// some code
}
class Manager : Employee
{
//some code
}
質問1: :これを行う他のコードがある場合:
Manager mgr = new Manager();
Employee emp = (Employee)mgr;
ここ Employee
aです Manager
, 、しかし、私がそれをそのようにキャストするとき Employee
それは私がそれをアップキャストしていることを意味しますか?
質問2:
私がいくつか持っているとき Employee
クラスオブジェクトといくつかは、それらのすべてではありませんが Manager
'S、可能な限りそれらをダウンキャストするにはどうすればよいですか?
解決
それは正しいです。あなたがそれをするとき、あなたはそれをキャストしています
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つのオペレーターを提供します - は ダウンキャストが機能するかどうかを示し、true/falseを返します。と なので キャストを実行しようとし、可能であれば正しいタイプを返します。そうでない場合は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");
- アップキャスティング サブクラスリファレンスから基本クラスの参照を作成する操作です。 (サブクラス - >スーパークラス)(つまりマネージャー - >従業員)
- ダウンキャスティング 基本クラスのリファレンスからサブクラスリファレンスを作成する操作です。 (SuperClass-> Subclass)(IE Employee-> 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
2番:
if (e is Manager){...} // the predicate is false if the downcast is not possible
警告: :アップキャストを行うと、スーパークラスのメソッド、プロパティなどにのみアクセスできます...
従業員の各オブジェクトがマネージャーオブジェクトであるかどうかを確認する必要がある場合は、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:はい、それはアップキャスティングと呼ばれましたが、あなたのやり方は現代的な方法ではありません。アップキャスティングは暗黙的に実行できます。変換は必要ありません。だからただ書くだけです 従業員emp = mgr;アップキャスティングには十分です。
回答2:マネージャークラスのオブジェクトを作成する場合、マネージャーは従業員であると言えます。なぜなら クラスマネージャー:従業員 描写します IS-A関係 従業員クラスとマネージャークラスの間。したがって、すべてのマネージャーが従業員であると言えます。
しかし、従業員クラスのオブジェクトを作成すると、この従業員がマネージャーであると言うことはできません。 クラスの従業員 他のクラスを継承していないクラスです。そのため、その従業員クラスオブジェクトからマネージャークラスオブジェクトへの直接ダウンキャストすることはできません。
答えは、従業員のクラスオブジェクトからマネージャークラスオブジェクトにダウンキャストしたい場合は、最初にマネージャークラスのオブジェクトが必要で、次にアップキャストしてからダウンキャストできます。
アップキャスティングとダウンキャスティング:
アップキャスティング:派生クラスからベースクラスへのキャスティングダウンキャスティング:ベースクラスから派生クラスへのキャスティング
例と同じことを理解しましょう:
次のように定義されている2つのクラスの形状を、派生クラスとして派生クラスとして、サークルと考えてください。
class Shape
{
public int Width { get; set; }
public int Height { get; set; }
}
class Circle : Shape
{
public int Radius { get; set; }
public bool FillColor { get; set; }
}
アップキャスティング:
shape s = new Shape();
円c = s;
CとSの両方が同じメモリの位置を参照していますが、どちらも「C」参照を使用して異なるビューを持っています。ベースクラスと派生クラスのすべてのプロパティにもアクセスできますが、「S」リファレンスを使用してプロパティにアクセスできます唯一の親クラスの。
アップキャスティングの実用的な例は、.NETフレームワークのあらゆるタイプのストリームリーダーのベースクラスであるストリームクラスです。
StreamReader Reader = new StreamReader(new FileStreamReader());
ここでは、FileStreamReader()がStreadM Rederにアップキャストされます。
ダウンキャスティング:
Shape S = new Circle();上で説明したように、Sのビューは唯一の親です。
var c =(circle)s;
ダウンキャスティングの実用的な例は、WPFのボタンクラスです。