将通用摘要 class<T> 作为参数传递
Passing a generic abstract class<T> as an argument
我有一个 classes 的等级制度:
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 个 class,每个都有 1 个 parent 和几个 children 例如:
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 class 中的字段,因此我需要像这样传递它
public APanel(AModel<T, U> aObject)
{
InitializeComponent();
_titleLabel.SetTitleString(aObject.Title);
}
如何将通用 AModel class 作为参数传递?
谢谢
您需要为类型参数提供值:
public APanel(AModel<Appellation, Bottle> aObject) { }
或者您还需要使 APanel
通用:
public class APanel<T,U> where T : class where U : class
{
public APanel(AModel<T, U> aObject) { }
}
如果面板不需要 AModel
的 "generic" 部分,我建议你为 AModel
创建一个非通用的 base-class 或接口,并在将其提供给 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);
}
泛型编程用于描述类型之间可互换的行为。
要在 APanel
控件中使用此通用行为,编译器需要知道用于构造 APanel
.
的类型
如果您打算将多个类型与 APanel
控件一起使用,请将 APanel
描述为通用类型。
对于 WinForms 控件,您需要更改 APanel.cs
和 APanel.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);
}
}
我有一个 classes 的等级制度:
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 个 class,每个都有 1 个 parent 和几个 children 例如:
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 class 中的字段,因此我需要像这样传递它
public APanel(AModel<T, U> aObject)
{
InitializeComponent();
_titleLabel.SetTitleString(aObject.Title);
}
如何将通用 AModel class 作为参数传递?
谢谢
您需要为类型参数提供值:
public APanel(AModel<Appellation, Bottle> aObject) { }
或者您还需要使 APanel
通用:
public class APanel<T,U> where T : class where U : class
{
public APanel(AModel<T, U> aObject) { }
}
如果面板不需要 AModel
的 "generic" 部分,我建议你为 AModel
创建一个非通用的 base-class 或接口,并在将其提供给 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);
}
泛型编程用于描述类型之间可互换的行为。
要在 APanel
控件中使用此通用行为,编译器需要知道用于构造 APanel
.
如果您打算将多个类型与 APanel
控件一起使用,请将 APanel
描述为通用类型。
对于 WinForms 控件,您需要更改 APanel.cs
和 APanel.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);
}
}