0

C#.NET4.5 と Visual Studio 2012 Ultimate を使用。

私は現在、ラベル印刷プログラムで抽象クラスを試しています。Ive Used Interfaces before.

インターフェイスを使用して 2 つのクラスを分離しました。うまく機能します。

今、私は次のことを試しています。

1位。私の抽象クラス...

abstract class Label
{

    public virtual IList<Microsoft.Reporting.WinForms.ReportParameter> NewReportSetup(string part, string batch, string locn, string wheel, string gear, string length,
                                string fits, string newbar, string newbarnum, string abs)
    {
        IList<Microsoft.Reporting.WinForms.ReportParameter> parameters = new List<Microsoft.Reporting.WinForms.ReportParameter>();
        parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramPart", part));
        parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramBatch", batch));
        parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramLocn", locn));
        parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramWheel", wheel));
        parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramGear", gear));
        parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramLength", length));
        parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramABS", abs));

        parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramBuyer", fits));
        parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramBarCode", newbar));
        parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramBartxt", newbarnum));

        return parameters;
    }
}

2番目。マイ ReportShaft はラベルを継承しています...

class ReportShaft : Label
{
    public virtual IList<Microsoft.Reporting.WinForms.ReportParameter> NewReportSetup()
    {         
        return new List<Microsoft.Reporting.WinForms.ReportParameter>();
    }
}

3番目。マイ フォームは ReportShaft クラスをインスタンス化し、NewReportSetup() を呼び出します...

private void NewReportSetupSHAFT()
{           
    if(txtABS.Text.ToString() == "" || txtABS.Text == null)
    {
        txtABS.Text = "N/A";
    }

    IList<Microsoft.Reporting.WinForms.ReportParameter> param = new List<Microsoft.Reporting.WinForms.ReportParameter>();

    param = reportshaft.NewReportSetup(txtNewPart.Text.ToString(),
        txtBatch.Text.ToString(), txtLocation.Text.ToString(), txtWheel.Text.ToString(), txtGear.Text.ToString(), txtLength.Text.ToString(),
        txtFits.Text.ToString(), txtNewBar.Text.ToString(), txtNewBarNum.Text.ToString(), txtABS.Text.ToString());

    reportViewer1.LocalReport.SetParameters(param);                        
}

これは問題なく動作します(ただし、抽象クラスを間違った方法で使用しているとは思いますが、よくわかりません)。

私の質問は:

新しいレポート クラスを作成したいと考えています。クラスがまったく同じメソッドを呼び出すようにしますが、上位 2 つのパラメーター名を変更し、最後のパラメーター名を完全にスキップできるようにします。

これには、メソッドのオーバーライドが必要ですか? もしそうなら、どのようにこれを行うでしょうか?Label メソッドはVirtual Functionから変更する必要がありますか?

どうもありがとう!

更新::パラメーターについて言及したとき、混乱しているように見えるかもしれません。

抽象クラスから 1 つのメソッドを呼び出したいと言いたいのですが、このラベル クラスとメソッドを継承するレポート クラスで、メソッドの本体を意味する「レポート パラメータ」を変更したいと思います。

この理由は、単純に別のメソッドを作成して、異なるレポートごとにそれを呼び出すと、ほぼ同じメソッドを使用することになるためです。

例を次に示します:: これを変更します。

parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramPart", part));

これも..

parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramchanged!!", part));

これは一例です。したがって、私が収集したものから、レポート クラスのラベル クラス メソッドをオーバーライドします。ボディを変更しようとすると、残りのコードを入力する必要があります。私にとっては、同じように見える一連のメソッドで終わることはまだあります。

とにかく、残りを入力することなく「メソッド本体の一部」を変更する方法はありますか?

これで混乱が解消されることを願っています。

4

2 に答える 2

2

あなたがしていることが最善のアプローチであるかどうかはわかりません。NewReportSetupがオブジェクトを受け取るようにコードをリファクタリングします。次に、アクセスするプロパティをオブジェクトに持たせることができます。それらが設定されていない場合は、それらを使用しないでください。その後、ビルダークラスを作成できます。

 NewReportSetup(ReportProperties propertiesObject)
 {
      ...
 }

 public class ReportProperties
 {
     public String Part{get;set;}
     ...
 }

ReportProperties次に、実装で指定されたオブジェクトを使用/フォーマットする子クラスを作成できます。

それ以外の場合、より直接的な答えは Micah のもので、これも機能します。違いは、継承よりも構成の 1 つです。継承にはそれなりの役割がありますが、合成の方が優れたアプローチである場合は、過度に使用しないでください。

あなたの更新のために

更新のためにできることは次のとおりです(ただし、ReportPropertiesオブジェクトは引き続き機能します...すべてのメタデータを含めることもできます)

あなたの抽象クラス:

public virtual void NewReportSetup(params)
{
    ...
    parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramBatch", batch));
    ...
    FinalizeParameters(parameters, paramsThatAreImplSpecific);
}

protected abstract void FinalizeParameters(List, paramsThatAreImplSpecific);

具体的な実装:

protected override void FinalizeParameters(List, paramsThatAreImplSpecific)
{
    parameters.Add( new Microsoft.Reporting.WinForms.ReportParameter("paramPart or paramChanged", part));
}

ここで、オーバーライドするルート実装を作成できますが、 Liskov の Substitution PrincipleFinalizeParametersを破らないように注意する必要があります。ディクショナリまたはその他のメカニズムを介して、適切なメタデータを持つオブジェクトを使用する必要があるように私には思えます。しかし、他の方法に進みたくない場合は、抽象メソッドを介して最終的なパラメーターの追加を強制することが最善の選択肢であると言えます。ReportProperties

于 2012-11-20T16:16:26.560 に答える
1

overrideではなく、基本クラスのメソッドをオーバーロードしたい。

オーバーロードによって署名が変更される機能の変更をオーバーライドします。あなたはこのようにこれを行うことができます

class ReportShaft : Label
{
  public virtual IList<Microsoft.Reporting.WinForms.ReportParameter> NewReportSetup()
    {
   base.NewReportSetup("part", "batch", "locn", "wheel","gear", "length", "fits", "newbar",  "newbarnum", null)

}
}

これは、同じパラメーターを多数使用する場合、または多数呼び出すデフォルトのパラメーターがある場合に役立ちます。また、作業中のクラスのメソッドではなく、基本クラスのメソッドを呼び出す base を呼び出していることにも注意してください。

于 2012-11-20T16:16:09.880 に答える