我正在使用委托来传递和存储单个表单Control
s的样式逻辑。例如,我有一个包含一些Button
如下样式逻辑的委托:
button.BackColor = Color.Red;
button.ForeColor = Color.White;
button.FlatStyle = FlatStyle.Flat;
当然,还有许多其他类型的控件,例如Labels,Panels等。因此,为了存储所有这些委托,我使用了Dictionary<Type, Delegate>
。
虽然,委托本身看起来像这样:
delegate void StyleDel<in T>(T control) where T : Control;
因此,为了使用字典中的逻辑,Delegate
必须首先将其强制转换为StyleDel<T>
-T
当时可能是这样。
在初始化并存储所有样式之后,必须应用样式(使用StyleDel
s)。为此,我做了一个功能StyleControl(control)
。
该函数查看控件的类型(例如a Button
),然后StyleDel
从中找到相应的控件Dictionary
,然后依次应用(Button
-)样式。
public void StyleControl<T>(T control) where T : Control
{
Delegate storedDel;
if (_dict.TryGetValue(control.GetType(), out storedDel))
{
// Cast Delegate to StyleDel
var styleDel = (StyleDel<T>) storedDel;
// Execute StyleDel
styleDel(control);
}
}
StyleDel
使用以下Add
功能将s添加到字典中:
public bool Add<T>(StyleDel<T> styleDel) where T : Control
{
var inDict = _dict.ContainsKey(typeof(T));
if (!inDict) _dict[typeof(T)] = styleDel;
return !inDict;
}
该StyleControl
函数由另一个函数调用,该函数确保所有内容都以递归方式设置:
public void Style<T>(T parent) where T : Control
{
StyleControl(parent);
// The problem might have to do with this
foreach (Control child in parent.Controls) Style(child);
}
InvalidCastException
抛出an ,表示StyleDel<Button>
无法将转换为StyleDel<Control>
。因此,我相信这T
是Control
在此时将其视为,而实际上是一个Button
。
如何Delegate
将其StyleDel<Button>
成功投放?
您可以通过添加独立级别来实现此目的;创建一个lambda来调用您的委托,将参数转换为正确的类型:
Dictionary<Type, StyleDel<Control>> _dict = ...
public bool Add<T>(StyleDel<T> styleDel) where T : Control
{
var inDict = _dict.ContainsKey(typeof(T));
if (!inDict) _dict[typeof(T)] = d => StyleDel((T)d);
return inDict;
}
乍一看,这似乎不是类型安全的,但是在这种特殊情况下,这是因为将委托存储在字典中,并且将参数的真实类型作为键。因此,按预期使用将始终确保始终使用正确键入的参数调用委托,并且不会发生运行时强制转换异常。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句