在 类 之间重用一个方法

Reusing a method between classes

关于代码 resuse 的一个 simple/beginner 问题,在一个记录机动车轮胎销售的基本 OOP 程序中。

轮胎存储在数组中:

public Tyre[] tyres = new Tyre[5];

我有两种形式。

Form1 最终用户只需使用 combo/lookup 个当前库存商品(轮胎)到 select 个商品。

public partial class Form1 : Form
    {
        Fitting fitting;
        public Tyre[] tyres = new Tyre[5];
        Tyre currentTyre;
        public Form1()
        {
            InitializeComponent();
            
            //populate array with tyres
            tyres[0] = new Tyre("155/80S13", 56.00m, 10);
            tyres[1] = new Tyre("165/70P15", 42.00m, 10);
            tyres[2] = new Tyre("195/70S13", 46.00m, 10);
            tyres[3] = new Tyre("158/90S19", 70.00m, 10);
            tyres[4] = new Tyre("185/66R13", 66.00m, 10);    
        }
        
        // search through array to find current selected tyre
        public  Tyre findTyre(string tyretype)
        {
            for (int i = 0; i < tyres.Length; i++)
            {
                if (tyretype == tyres[i].Type)
                    return tyres[i];
            }
            return null;
        }

 private void cmbTyreType_SelectedIndexChanged(object sender, EventArgs e)
        {
            currentTyre = findTyre(cmbTyreType.Text);
            lblPrice.Text = currentTyre.Price.ToString();
            lblStockQ.Text = currentTyre.StockQty.ToString();
        }

findTyre() 方法定义为:

public  Tyre findTyre(string tyretype)
        {
            for (int i = 0; i < tyres.Length; i++)
            {
                if (tyretype == tyres[i].Type)
                    return tyres[i];
            }
            return null;
        }

表格 2 (AddStock) 在此表格上,最终用户当前再次使用类似的 combo/lookup 来查看轮胎范围(就像在表格 1 上一样)

public partial class AddStock : Form
    {
        Form1 frm2;
        Tyre currentTyre;
       
        public AddStock(Form1 frm)
        {
            frm2 = frm;
            InitializeComponent();
            for (int i = 0; i< frm.tyres.Length ; i++)
            {
                cmbTyreType.Items.Add(frm.tyres[i].Type);
            }
        }

        public Tyre findTyre(string tyretype )
        {
            for (int i = 0; i < frm2.tyres.Length; i++)
            {
                if (tyretype == frm2.tyres[i].Type)
                    return frm2.tyres[i];
            }
            return null;
        }

        

        private void cmbTyreType_SelectedIndexChanged(object sender, EventArgs e)
        {
            currentTyre = findTyre(cmbTyreType.Text);
            lblCurrentQ.Text = currentTyre.StockQty.ToString();
        }

我担心的是我不得不再次重新定义 findTyre(),尽管它已在 Form1 中定义。我希望(也许消息不灵通)我可以重新使用 Form1 中的 findTyre() 方法,但是 Visual Studio 阻止了我。

原因可能是 findTyre() 方法绑定到实例,导致它在 class 之外无法访问?

创建一个 class 来管理您的轮胎:

public class Tyres
{
   private Tyre[] tyres = new Tyre[5];

   public Tyre this[int i]
   {
      get { return tyres[i]; }
      set { tyres[i] = value; }
   }

   public Tyre findTyre(string tyretype )
   {
       for (int i = 0; i < frm2.tyres.Length; i++)
       {
          if (tyretype == frm2.tyres[i].Type)
              return frm2.tyres[i];
       }
       return null;
   }
}

不是在表单之间传递数组,而是传递此 class 的一个实例。这个 class 还可以包含更具体的方法,这些方法对你的轮胎进行操作。这是 OOP 的一个基础:将数据和作用于该数据的方法保持在一起(在 class 中)。这也有助于您将逻辑与 GUI 分开。假设您想将 winforms 应用程序更改为控制台或 Web 应用程序。在那种情况下,您可以重复使用轮胎 class。搜索轮胎与 GUI 无关,这就是为什么它不属于 class.

形式的原因

在 AddStock 中,您不能只使用 Form1 中的 findTyre 方法吗?

currentTyre = frm2.findTyre(cmbTyreType.Text);

看来您可以从 Form1

调用 findTyre
public Tyre findTyre(string tyretype)
=> frm2.findTyre(tyretype)

为什么 findTyre 方法在表单 class 内而不是在 Tires class 内? 在你的情况下,我只是将方法移动到 Tire 对象中 class 使其成为静态的并向该方法添加一个新参数。

在你的程序中有重复的方法从来都不是一件好事。原因是如果该方法在功能上发生变化,您将不得不在整个程序的任何地方而不是一个地方更改它。也总是尝试将您的对象特定代码绑定到您的对象 class。所以你知道如果你需要一个与轮胎相关的方法,你只需要查看轮胎 class 而不是通过你所有的 classes 试图找到它。

我建议您还阅读以下文章,它解释了关注点分离是什么:https://www.castsoftware.com/blog/how-to-implement-design-pattern-separation-of-concerns

     public static Tyre findTyre(string tyretype, Tyres[] Tyres )
    for (int i = 0; i < tyres.Length; i++)
        {
            if (tyretype == tyres[i].Type)
                return tyres[i];
        }
        return null;
    }

我还建议您实施下面答案中提供的代码@SomeBody。将使您的代码更清洁、更可持续。