这是使用通用方法的好方法吗?

时间:2013-11-13 05:16:18

标签: c# generics methods

以下是我的代码。

public class baseMenuItem : MenuItem
{        
    public baseMenuItem()
    {
        this.Click += baseMenuItem_Click;
    }

    void baseMenuItem_Click(object sender, RoutedEventArgs e)
    {
        //When user click the menu, I will need to new a window which type is assigned from AssignHandleWindow<T>()
    }

    public void AssignHandleWindow<T>() where T : baseWindow 
    {
        //Can I save <T> into somewhere for later Click-event using?
        //How do I do that?
    }
}

我不确定这是否可行,但我的应用程序中可能有40个以上的menuItem,我不想为每个人编写click事件来打开窗口,有什么想法吗?

感谢。

4 个答案:

答案 0 :(得分:1)

这里的反思可能是更好的选择。您可以通过控件(http://msdn.microsoft.com/en-us/library/system.windows.forms.control.tag%28v=vs.110%29.aspx)上的Tag属性将自定义数据与控件相关联。您可以将要打开的窗口的完全限定类型名称分配给标记(通过设计器或通过代码)。通过代码,它看起来像这样:

menuItem.Tag = "namespace.class, dllname";

然后在通用事件处理程序中执行以下操作(我的Win Forms有点生疏,但它应该让您知道您需要做什么):

void baseMenuItem_Click(object sender, RoutedEventArgs e)
{
    Control senderAsControl = (Control)sender;
    Type windowType = Type.GetType((string)(senderAsControl.Tag));
    Control window = (Control)Activator.CreateInstance(windowType);
    window.Show();
}

这种完全未经测试的通常序言适用。

答案 1 :(得分:1)

您可以在字段中保存类型,然后使用

public class baseMenuItem : MenuItem
{        
    Type windowType;
    public baseMenuItem()
    {
        this.Click += baseMenuItem_Click;
    }

    void baseMenuItem_Click(object sender, RoutedEventArgs e)
    {
        if(windowType != null){
            window = (Control)Activator.CreateInstance(windowType);
            window.Show();
        }
    }

    public void AssignHandleWindow<T>() where T : baseWindow 
    {
        windowType = typeof(T);
    }
}

答案 2 :(得分:0)

public T AssignHandleWindow<T>() where T : baseWindow, new() 
{
    var window = new T();
    return window;
}

以上工作可以吗?

然后,您可以通过点击处理程序调用此方法。

答案 3 :(得分:0)

我最近使用

填充了一个下拉菜单
var thingsForMenu = getThingsForMenuBasedOnWhasClickedOn();
foreach(var v in thingsForMenu) {
    ToolStripItem ti = new ToolStripMenuItem(v.key);
    var localItem c = v.value;
    ti.onClick += (o,ie) => {
         doTheThing(c);
    }
    ToolStrip.DropDownItems.Add(ti);
}

注意:c的局部变量副本是关键的,因为v在循环内部被重新分配,并且你需要将指针传递给c in,而不仅仅是在函数返回后v.value在内存中持续存在的值(通常导致所有菜单项调用相同的东西)

这不是“我如何使用泛型”回答您的问题,但确实提供了一种机制来将信息传递到onClick处理程序。