假设我有以下代表
public delegate void ControlInitializer(Control control);
Run Code Online (Sandbox Code Playgroud)
有没有办法在指定委托时指定输入参数是什么类型的控件?例如
代替
ControlInitializer one = c => ((TextBox)c).Text = "Init Value"
ControlInitializer two = c => ((DropDownList)c).SelectedValue= "-1"
Run Code Online (Sandbox Code Playgroud)
我能做点什么吗
ControlInitializer one = (TextBox c) => c.Text = "Init Value"
ControlInitializer two = (DropDownList c) => c.SelectedValue= "-1"
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Textbox是Control的子类吗?
更新:我还需要将这两个ControlInitialiser委托存储在例如
Dictionary<string, ControlInitializer>
Run Code Online (Sandbox Code Playgroud)
将指定
Dictionary<string, ControlInitializer<Control>>
Run Code Online (Sandbox Code Playgroud)
在这种情况下工作,因为我似乎无法让它工作.
提前致谢.
dtb*_*dtb 10
您可以使委托通用:
public delegate void ControlInitializer<TControl>(TControl control)
where TControl : Control;
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
ControlInitializer<TextBox> one = c => c.Text = "Init Value";
ControlInitializer<DropDownList> two = c => c.SelectedValue = "-1";
Run Code Online (Sandbox Code Playgroud)
我想你的目标是这样的:
var init = new Init();
init.RegisterInitializer<TextBox>(c => c.Text = "Init Value");
init.RegisterInitializer<DropDownList>(c => c.SelectValue = "-1");
foreach (var c in Controls)
{
init.ApplyInitializer(c);
}
Run Code Online (Sandbox Code Playgroud)
由于David B回答中提到的原因,这有点困难.但是,你可以做的是隐藏抽象背后的类型,如下所示:
public class Init
{
private readonly Dictionary<Type, Action<Control>> initializers;
...
public void RegisterInitializer<TControl>(Action<TControl> i)
where T Control : Control
{
initializers.Add(typeof(TControl), c => i((TControl)c));
}
public void ApplyInitializer(Control c)
{
initializers[c.GetType()](c);
}
}
Run Code Online (Sandbox Code Playgroud)