假设我有以下代表
public delegate void ControlInitializer(Control control);
指定委托时是否有办法指定输入参数的控制类型? e.g。
而不是
ControlInitializer one = c => ((TextBox)c).Text = "Init Value"
ControlInitializer two = c => ((DropDownList)c).SelectedValue= "-1"
我可以做点什么吗
ControlInitializer one = (TextBox c) => c.Text = "Init Value"
ControlInitializer two = (DropDownList c) => c.SelectedValue= "-1"
在这种情况下,Textbox是Control的子类吗?
更新:我还需要将这两个ControlInitialiser委托存储在例如
Dictionary<string, ControlInitializer>
将指定
Dictionary<string, ControlInitializer<Control>>
在这种情况下工作,因为我似乎无法让它发挥作用。
提前致谢。
答案 0 :(得分:10)
您可以使委托具有通用性:
public delegate void ControlInitializer<TControl>(TControl control)
where TControl : Control;
然后像这样使用它:
ControlInitializer<TextBox> one = c => c.Text = "Init Value";
ControlInitializer<DropDownList> two = c => c.SelectedValue = "-1";
我想你的目标是这样的:
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);
}
由于 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);
}
}
答案 1 :(得分:3)
首先,使用预定义的委托Action
。关于指定类型,请使用泛型参数:
Action<TextBox, string> one = (c,v) => c.Text = v;
Action
委托最多需要4个参数,不会返回任何内容(void
)。
答案 2 :(得分:2)
您无法将ControlInitializer<TextBox>
添加到包含ControlInitializer<Control>
的词典,因为第一种类型不会继承第二种类型(即使{{1}继承自TextBox
。)这是关于泛型中缺乏协方差和逆变的全部内容。
您可以编写自己的集合,以您期望的方式行事。这是一种可能性:
Control
可以这样使用:
public class CustomStorage
{
private Dictionary<string, object> storage = new Dictionary<string, object>();
public void Remember(string key, object value)
{
storage[key] = value;
}
public object Retrieve(string key)
{
object x = storage[key];
return x;
}
public U Retrieve<U>(string key)
{
U u = (U) storage[key];
return u;
}
}