0

我有一种过滤/搜索方法,现在是为每个Windows Form提供搜索的方法编写的。我正在尝试在基类中创建一个通用方法,这样我就可以避免大量重复代码。

这是我要修改的原始代码:

private void LoadData()
{
    GridFilter filter = new GridFilter();
    filter.AddRule(dgvColDescription.DataPropertyName, txtDescription.Text);

    if (cboColor.SelectedIndex != -1)
    {
        filter.AddRule(dgvColMaterialColorId.DataPropertyName, cboColor.SelectedValue.ToString());
    }
    ...
    //a lot more of this filter.AddRule stuff 
    ...
 }

我认为这里有两件事——实例的需要GridFilter和我需要使用的两种类型的控件。

话虽如此,这是我对通用方法的尝试:

protected virtual void AddFilterRules<T>(Control ctrl, String str) where T : GridFilter
{
    T filter;
    if (ctrl is ComboBox)
    {
        if ((ctrl as ComboBox).SelectedIndex != -1)
        {
            filter.AddRule(/*dgvColMaterialColorId.DataPropertyName*/ str, (ctrl as ComboBox).SelectedValue.ToString());
        }
    }

    if (ctrl is TextBox)
    {
        filter.AddRule(/*dgvColCode.DataPropertyName*/str, ctrl.Text);
    }
}

有一些评论,因为我仍然不确定是否可以将评论部分作为字符串传递,但对我来说更大的问题是我从IDEaboutfilter变量中得到的错误是:

使用未分配的局部变量“过滤器”

毕竟有可能用它制作一个通用方法吗?我该怎么做?

4

4 回答 4

2

new()约束添加到您的方法中。

protected virtual void AddFilterRules<T>(Control ctrl, String str) where T : GridFilter, new()

进而

T filter = new T();

要么将 T 作为参数传入:

protected virtual void AddFilterRules<T>(T filter, Control ctrl, String str) where T : GridFilter
于 2013-03-01T14:47:38.563 回答
1

您的语法是正确的,但您还有另外两个问题:

  1. 你没有初始化T任何东西。它是null您尝试使用它时的参考。你打算传入一个T吗?

  2. 没有T. 你应该退货T?或者将其分配给其他对象的属性?

如果传入对 a 的引用T,然后在方法中对其进行修改,那么这两个问题都解决了:

protected virtual void AddFilterRules<T>(T filter, Control ctrl, String str)
     where T : GridFilter
{
    ...
}

但是,在这种情况下,您的方法根本不需要是通用的:

protected virtual void AddFilterRules(GridFilter filter, Control ctrl, String str)
{
    ...
}
于 2013-03-01T14:47:45.353 回答
1

为什么要使用泛型方法?

如果您的过滤器始终是 aGridFilter您可以在您的方法中使用该类型。即使您使用这样的派生类SpecialGridFilter仍然可以工作。事实上,在您的原始方法中,您GridFilter每次都创建一个新方法,这意味着您可以在您的新方法中这样做。因此,尽管您现在将一些值传递给它,但不需要新方法。

看起来您将类型参数与普通参数混合在一起。拥有类型参数并不意味着您获得了该类型的实例。这只是意味着您可以对不同类型使用相同的算法,而无需为每种类型显式编码。

如果你真的需要一个泛型实现,你可以对泛型参数使用类型约束where T : GridFilter, new()。这允许您在通用方法中创建一个new T()

新方法将在哪里实施?

我不知道GridFilter现在是如何实现的,但它看起来像AddRule修改它。如果是这样,您不应该每次都创建一个新实例,因为所有更改都会丢失。AddFilterRules因此也应该是GridFilter类的成员,并且每个表单都应该有一个GridFilter.

如果您无法更改实现,GridFilter您仍然可以使用扩展方法。如果GridFilter每次都创建一个新的是正确的,那么您可以在该Form类型上有一个扩展方法。这取决于如何GridFilter工作。

于 2013-03-01T15:24:43.450 回答
0

您应该创建一个 T 的实例:

T filter = new GridFilter();

如果 T 总是 a GridFilter,你也可以用 GridFilter 替换 T:

protected virtual void AddFilterRules<GridFilter>(Control ctrl, String str)
{
    GridFilter filter = new GridFilter();
    ...
}

但是,我认为您根本不应该使用通用方法。您应该创建一个返回 GridFilter 的方法:

protected virtual GridFilter AddFilterRules(Control ctrl, String str)
{
    GridFilter filter = new GridFilter();
    ...

    return filter;
}
于 2013-03-01T14:48:18.077 回答