【问题标题】:C# Abstract Class Override methodC# 抽象类重写方法
【发布时间】:2012-11-20 16:03:26
【问题描述】:

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

我目前正在尝试使用我的标签打印程序 Ive Used Interfaces 之前的抽象类。

我使用接口来解耦我的两个类,效果很好。

现在我正在尝试以下内容。

第一个。我的抽象类...

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;
    }
}

第二次。我的 ReportShaft 继承标签...

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

3rd. 我的表单实例化 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个参数名称,并跳过最后一个完全。

现在这需要对方法进行 overide 吗?如果是这样,人们将如何做到这一点? Label 方法是否需要从 Virtual Function 进行更改?

非常感谢各位!

更新:: 好吧,当我提到参数时,似乎有些混乱。

我的意思是说我希望从我的抽象类中调用 1 方法,然后在我继承此标签类和方法的报告类中,我希望更改“报告参数”,我的意思是方法的主体。

这样做的原因是,如果我只是简单地创建另一个方法并为每个不同的报告调用它,我将使用几乎相同的方法。

这里的例子:: 改变这个..

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

这也是..

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

这是一个例子。因此,根据我收集到的信息,我在我的报告类中覆盖了我的标签类方法。但是后来我卡住了,如果我尝试更改正文,我必须输入其余的代码。对我来说,我仍然会得到一堆看起来相同的方法。

有没有办法改变“方法主体的部分部分”而不必输入其余部分。

希望这能消除混乱。

【问题讨论】:

    标签: c# overriding virtual abstract-class


    【解决方案1】:

    我不确定您正在做的是最好的方法。我会重构代码以便NewReportSetup 接受一个对象。然后,您可以让对象具有您可以访问的属性,如果没有设置它们,那么您就不要使用它们。然后您可以创建一个builder 类。

     NewReportSetup(ReportProperties propertiesObject)
     {
          ...
     }
    
     public class ReportProperties
     {
         public String Part{get;set;}
         ...
     }
    

    然后,您可以创建使用/格式化给定的ReportProperties 对象的子类,如实现所指定的

    否则,更直接的答案是 Micah 的,它也有效。区别是Composition over Inheritance 之一。继承有它的位置,但当组合是更好的方法时,不应该过度使用

    供您更新

    这听起来像是您可以为更新做的事情(但是,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));
    }
    

    现在,您可以使 FinalizeParameters 具有您覆盖的根实现,但您要小心破坏 Liskov's Substitution Principle。在我看来,您确实应该使用带有适当元数据的ReportProperties 对象,无论是通过字典还是其他机制。但是,如果您不想采用任何其他方式,我会说通过抽象方法强制添加最终参数是您的最佳选择。

    【讨论】:

    • 这是个好主意,不是你做错了,而是你需要从大局出发,确保它是你需要的。
    • 是的,现在设计就是天堂,但我的老板不理解“设计”的概念,他喜欢“已经完成”这个词,所以我必须在飞行中思考,所以我为什么会得到当我看到我也进行了 OOP 更改并由于一开始的错误设置而迷路时卡住了。
    • 务实是把事情做好的必要条件,但不要害怕重构:)
    • 我明白你的意思了,我已经开始了重构过程,我很想知道这是否可以完成,非常感谢!
    【解决方案2】:

    你想overload基类中的方法而不是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 ,它将调用基类方法而不是我正在使用的类中的方法

    【讨论】:

    • 是的,大部分参数将被重复使用,只有少数更改取决于报告。我唯一不确定的是base.NewReportSetup,您传入的字符串是名称吗?正如我所说的,例如我想将“paramPart”更改为“paramDifferentPart”,而我根本不想使用 abs。
    • 是的,传递您的默认值我无法知道这些值是什么。如果你根本不想传递abs那么你可以传递null,我可以改变我的例子
    • 对不起,我仍然不确定这是如何工作的,这个类将被我的表单实例化,然后这个方法将被调用,它会将一堆字符串传递给从标签继承的方法,标签然后设置参数名称和参数值示例(“paramPart”,part)。我想更改“paramPart”。我也想完全跳过 ABS 参数。
    • 你不明白我的参数吗?我需要帮助了解您不了解的内容
    • 稍微迷路了。原谅我这是漫长的一天。 base.NewReportSetup 方法将值传递给该方法的每个参数。如果您查看 Labe 类,您会看到该方法有一个主体,主体包含对“reportParamters”的调用。我在徘徊是否可以更改“reportParameters”的“名称”(而不是方法参数)。所以取第一行:parameters.Add(new Microsoft.Reporting.WinForms.ReportParameter("paramPart", part));我想更改“paramPart”并且我想跳过方法底部的 ABS 报告参数。
    猜你喜欢
    • 1970-01-01
    • 2014-05-30
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 2021-03-13
    • 2011-12-26
    • 2014-08-28
    • 1970-01-01
    相关资源
    最近更新 更多