将通用抽象类<t>作为参数传递</t>

时间:2015-02-15 21:30:17

标签: c# templates generics arguments base

我有一个类的层次结构系统:

public abstract class AModel<T,U> where T : class where U : class
{
    protected IList<U> _children;
    protected readonly T _parent;
    protected readonly String _name;
    protected readonly String _urlStr;
    protected String _title;

    protected AModel(T parent, String name, String urlStr)
    {
        _parent = parent;
        _name = name;
        _urlStr = urlStr;
    }
    ...
}

我将它用于5个类,每个类有1个父节点和几个子节点,例如:

public class Domain : AModel<Appellation, Bottle>
{        
    public Domain(Appellation pAppellation, string name, string urlStr) : base (pAppellation, name, urlStr)
    {
        _title = "Domaine : " + _name;
    }
    ...
}

这对于处理树视图非常有用

foreach (Domain domain in appellation.Children)
{
    _domains.Add(domain);
    domain.SetChildren(ReferentialDbManager.Instance.SelectBottles(domain));
    ...
}

现在我的问题是我想在以下情况下从我的树视图中将AModel传递给UserControl构造函数:

private void OnSelectedNodeChange(object sender, TreeViewEventArgs e)
{
    _selectionGroupBox.Controls.Clear();
    switch (e.Node.Tag.ToString())
    {
        case "DOMAIN":
            AModel<Appellation, Bottle> selectedDomain = ReferentialManager.Instance.FindDomain(e.Node.Text);
            _selectionGroupBox.Controls.Add(new APanel(selectedDomain) { Dock = DockStyle.Fill });
            break;
        ...
    }
    ...
}

在APanel中,我将使用基本AModel类中的字段,因此我需要传递它,如

public APanel(AModel<T, U> aObject)
{
    InitializeComponent();
    _titleLabel.SetTitleString(aObject.Title);
}

如何将通用AModel类作为参数传递?

由于

2 个答案:

答案 0 :(得分:0)

您需要为类型参数提供值:

public APanel(AModel<Appellation, Bottle> aObject) { }

或者你也需要APanel通用:

public class APanel<T,U> where T : class where U : class
{    
    public APanel(AModel<T, U> aObject) { }
}

如果面板不需要&#34;泛型&#34; AModel的一部分,我建议您为AModel创建一个非通用的基类或接口,并在将其提供给APanel之前将其强制转换为:

public abstract class AModelBase {
    // non-generic stuff
    protected readonly String _name;
    protected readonly String _urlStr;
    protected String _title;
}

public abstract class AModel<T,U> : AModelBase where T : class where U : class
{
    // generic stuff
    protected IList<U> _children;
    protected readonly T _parent;    
}

public APanel(AModelBase model)
{
    InitializeComponent();
    _titleLabel.SetTitleString(model.Title);
}

答案 1 :(得分:0)

通用编程用于描述类型之间可互换的行为。

要在APanel控件中使用此通用行为,编译器需要知道用于构造APanel的类型。

如果您打算在APanel控件中使用多种类型,请将APanel描述为通用类型。

对于WinForms控件,您需要更改APanel.csAPanel.Designer.cs文件。

APanel.cs

public partial class APanel<TParent, TChild> : UserControl
    where TParent: class
    where TChild: class

{
    public APanel(AModel<TParent, TChild> model)
    {
        InitializeComponent();
        _titleLabel.SetTitleString(model.Title);
    }
}

APanel.Designer.cs

partial class APanel<TParent, TChild>
{
    // Change the type declaration
    // leave the inside of the class alone
}

否则,您需要为构造函数提供完整的具体类型。

public class APanel : UserControl
{
    public APanel(AModel<Appellation, Bottle> model)
    {
        InitializeComponent();
        _titleLabel.SetTitleString(model.Title);
    }
}