静态成员访问

时间:2011-09-13 21:19:46

标签: c# static-methods

我可能会对这一切都不对,但我有一个名为CategoryControl的用户控件,可能会有很多人喜欢它,因此我决定将其许多功能更好地用作静态方法。我想知道是否有一种“更好”的方式来访问这些方法,然后在整个类中传递一个实例。这些方法是公共静态的,因为它们将通过其他方法更新。我想到了制作扩展方法的方法..?

public CategoryControl(UserCategory userCategory)
{
   InitializeComponent();

   PopulateControl(userCategory, this);
}

private static void PopulateControl(UserCategory userCategory, CategoryControl instance)
{

   SetCategoryTitle(userCategory, instance);

   SetPercentCorrect(userCategory, instance);

   SetQuestionsMissed(userCategory, instance);

   SetBackgroundBar(userCategory, instance);

   SetForegroundBar(userCategory, instance);

}

更新::

较长的故事是我在屏幕上有一个Panel,该面板包含相关的用户类别。相关我的意思是用户可以选择更改课程,从而显示一组新的类别。用户还可以基于他们与软件的交互来改变类别的值。所以......

面板显示课程的类别。

我在面板中维护一个活动的类别控件列表,主窗体告诉面板何时绘制一组新的类别。

public void InitializeProgressPanel(UserCategories parentCategories)
{
   Contract.Requires(parentCategories != null, "parentCategories is null.");

   RemoveAllControlsFromList(_categoryControls);

   UserCategories sortedUserCategories = parentCategories.SortByWorst();

   int categoriesCount = parentCategories.Count();

   int spacer = (Height - (CategoryControl.Controls_Height * categoriesCount)) / categoriesCount+1;

   for (int i = 0; i < sortedUserCategories.Count; i++)
   {
      CategoryControl cc = new CategoryControl((UserCategory)sortedUserCategories[i]);

      cc.Left = 0;

      if (i == 0)
         cc.Top = spacer;
      else
         cc.Top = (Controls[i - 1].Bottom + spacer);

      Controls.Add(cc);
      _categoryControls.Add(cc);

      }
}

5 个答案:

答案 0 :(得分:8)

如果我有一个可以扩展的课程,我肯定不会制作扩展方法。请记住,扩展方法的目的是扩展您无法扩展自己的类型。

当时的问题是,如果你说:

class C 
{
    public void Foo() { ... }
}

class C
{
    public static void Foo(C c) { ... }
}

我会问一些问题:

  • 该课程是否会被分类?如果是这样,这应该是一个虚拟方法吗?
  • Foo是一个实例对自己做的事情,还是它对它做过的事情?动物独自吃,但动物由其他人喂食

更新:

我会问自己一些问题:

  • 您所设置的属性和属性是否会发生变化?您在课堂上的可变性越小,测试就越容易,推理就越容易,而且您拥有的错误就越少。如果属性和诸如此类的东西永远不会改变,那么不要在任何类方法中设置它们。在构造函数中设置它们然后再也不用担心它们了;他们是对的。

答案 1 :(得分:1)

为什么不让他们成为实例成员,并按照这样做

private UserCategory _userCategory;

public CategoryControl(UserCategory userCategory)
{
   InitializeComponent();

   this._userCategory = userCategory;
   this.PopulateControl();
}

private void PopulateControl()
{
   // to see userCategory you'd do "this._userCategory"
   // to see the specific instance you could simply do "this"

   SetCategoryTitle();

   SetPercentCorrect();

   SetQuestionsMissed();

   SetBackgroundBar();

   SetForegroundBar();

}

答案 2 :(得分:1)

似乎更好地在交互中涉及的两个类之一上具有功能,而不是在某些第三方上。

以下是两种让人想起的方法:

  1. CategoryControl可以有一个公共函数PopulateCategory(UserCategory userCat)
  2. UserCategory可以有一个公共函数PopulateFromControl(CategoryControl ctrl)
  3. 如果所有关于标题和百分比等的操作都需要单独操作,那么您只需遵循上面的模型,但每个项目都有不同的功能。

答案 3 :(得分:1)

这里只是一个黑暗的镜头,但我可能会尝试更像这样的东西:

private void PopulateControl(UserCategory userCategory)
{
    CategoryTitle = GetCategoryTitle(userCategory);
    PercentCorrect = GetPercentCorrect(userCategory);
    ...
}

答案 4 :(得分:0)

有些问题可能会有所帮助......(?)

  • 您认为使方法静态有什么好处?将方法转换为静态,您将删除“this”的隐式传递,并且每次都手动传递。这有什么用? (它不会使代码更有效,它只是意味着你必须将'实例'传递给你所做的每一次调用,所以你需要编写更多的代码)

  • 用户类别是否会发生很大变化?如果没有,而不是为每次调用传递它,那么将它变成成员变量会更有意义吗?

  • 您是否真的想逐个调用所有这些静态方法来更改控件的所有不同参数?看看客户端将如何使用这个类,你可能会发现你可以将所有这些选项转换为一个或两个方法,这些方法接受一堆参数并在一次命中中应用它们。 (通常,如果您想更改一个设置,则需要同时更改多个设置)