私はC#を初めて使用し、基本的な概念を理解しようとしています。よろしくお願いします。以下にいくつかのサンプルクラスがあり(このウィンドウに入力されているため、エラーが発生する可能性があります)、2つの質問があります。
同じ名前の基本クラスメソッドのコードを実行してから、派生クラスメソッドのコードを実行する派生クラスメソッドを呼び出すことは可能ですか?すべての派生クラスは、RunCheckの基本クラスコードを実行してから、そのクラスに固有の特殊なコードを実行する必要があります。基本クラスでRunCheck()に別の名前を付けて、派生クラスのRunCheck()を呼び出すときに呼び出すこともできますが、派生クラスのRunCheck()で呼び出すことを忘れないでください。
Program.csで、渡した派生クラスにないフィールドにある場合、空白の値ですべてのフィールドを出力したいと思います。何を渡しますか?
これが私のコードです:
class baseCheck
{
public DateTime StartTime { get; set; }
public DateTime LastRun { get; set; }
public int Runs { get; set; }
//Others
public void RunCheck()
{
if (Started != null)
started = DateTime.Now;
LastRun = DateTime.Now;
Runs++;
}
}
class FileCheck : baseCheck
{
public string FileName { get; set; }
public void RunCheck()
{
//I want all the code in the base class to run plus
//any code I put here when calling this class method
}
}
class DirectoryCheck : baseCheck
{
public string DirectoryName { get; set; }
public void RunCheck()
{
//I want all the code in the base class to run plus
//any code I put here when calling this class method
}
}
//Program.cs
static void Main()
{
//Create derived class - either DirectoryCheck or FileCheck
//depending on what the user chooses.
if (Console.ReadLine()=="F")
{
FileCheck c = new FileCheck();
}
else
{
DirectoryCheck c = new DirectoryCheck();
}
PrintOutput(c);
}
private void PrintOut(What do I put here?)
{
Console.WriteLine("Started: {0}",f.StartTime)
Console.WriteLine("Directory: {0}", f.DirectoryName)
Console.WriteLine("File: {0}", f.FileName}
}
DirectoryCheck
クラスでbase.RunCheck()
を呼び出すだけです。
_public class DirectoryCheck : baseCheck
{
public string DirectoryName { get; set; }
public void RunCheck()
{
//I want all the code in the base class to run plus
//any code I put here when calling this class method
base.RunCheck();
Console.WriteLine("From DirectoryCheck");
}
}
_
また、現在の実装では、基本クラスのRunCheck()
メソッドを非表示にしています-実際にオーバーライドする必要があります-これにより、基本クラスのメソッドシグネチャが次のように変更されます。
_ public virtual void RunCheck()
_
および派生クラスで
_ public override void RunCheck()
_
非仮想インターフェース パターン(NVI)-保護された仮想メソッドを基本クラスで公開します。子クラスはオーバーライドできますが、基本にパブリックメソッドがあります。そのメソッドを内部で実際に呼び出しているクラス-このアプローチにより、その呼び出しの前後に実行していることを拡張できます。
あなたの例では、これは次のようになります。
_class BaseCheck
{
private DateTime Started { get; set; }
public DateTime StartTime { get; set; }
public DateTime LastRun { get; set; }
public int Runs { get; set; }
//Others
public void RunCheck()
{
if (Started != null)
Started = DateTime.Now;
LastRun = DateTime.Now;
Runs++;
CoreRun();
}
protected virtual void CoreRun()
{
}
}
public class DirectoryCheck : BaseCheck
{
public string DirectoryName { get; set; }
protected override void CoreRun()
{
//I want all the code in the base class to run plus
//any code I put here when calling this class method
Console.WriteLine("From DirectoryCheck");
}
}
_
派生クラスでは、以下を使用して基本クラスのメソッドを呼び出すことができます。
_public override void RunCheck()
{
base.RunCheck();
// Followed by the implementation of the derived class
}
_
コメントで述べたように、オーバーライドを許可するには、基本メソッドをvirtual
として宣言する必要があります。
_public virtual void RunCheck() { ... }
_
PrintOut()メソッドには魔法の方法はありませんが、基本クラスをパラメーターとして受け取り、型をテストすることができます。
_private void PrintOut(baseCheck f)
{
Console.WriteLine("Started: {0}", f.StartTime)
Console.WriteLine("Directory: {0}", f.DirectoryName)
if (check is FileCheck)
{
Console.WriteLine("File: {0}", ((FileCheck)f).FileName}
}
}
_
または、オーバーロードを使用できます。
_private void PrintOut(baseCheck f)
{
Console.WriteLine("Started: {0}", f.StartTime)
Console.WriteLine("Directory: {0}", f.DirectoryName)
}
private void PrintOut(FileCheck f)
{
PrintOut((baseCheck)f);
Console.WriteLine("File: {0}", ((FileCheck)f).FileName}
}
_
または、PrintOutメソッドをクラスの一部にして(おそらく既存のToString()
メソッドを使用することもできます)、必要に応じてオーバーライドすることもできます。