我使用委托传递并存储单个表单Control
的样式逻辑。例如,我有一个代理包含一些Button
- 样式逻辑,如下所示:
button.BackColor = Color.Red;
button.ForeColor = Color.White;
button.FlatStyle = FlatStyle.Flat;
当然,还有许多不同类型的控件,如标签,面板等。所以为了存储所有这些代表,我使用Dictionary<Type, Delegate>
。
虽然,代表本身看起来像这样:
delegate void StyleDel<in T>(T control) where T : Control;
因此,为了使用字典中的逻辑,Delegate
必须首先转换为StyleDel<T>
- 无论T
当时可能是什么。
在初始化并存储所有样式之后,必须应用样式(使用StyleDel
s)。为此我创建了一个函数StyleControl(control)
。
此函数查看控件的类型(例如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
被添加到字典中,下面是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
抛出StyleDel<Button>
,说StyleDel<Control>
无法转换为T
。所以我相信它会说Control
此时被视为Button
,而它实际上是Delegate
。
如何成功地将此StyleDel<Button>
投射到repcomb <- function(v,n,ind)
{
k <- length(v)
if(ind == 0)
{
for (i in 1:k) v[i] <- 1
ind <- 1
return(list(v=v, ind=ind))
}
for (i in k:1)
{
if(v[i] != n)
{
for (j in i+1:k) v[j] <- v[i] + 1
v[i] <- v[i] + 1
return(list(v=v, ind=ind))
}
}
ind = 0
return(list(v=v, ind=ind))
}
res <- repcomb(1:5, 4, 2)
v <- res$v
ind <- res$ind
?
答案 0 :(得分:3)
您可以通过添加一定程度的疏忽来实现这一目标;创建一个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;
}
乍一看,这似乎不是类型安全的,但在这种特殊情况下,它将是因为委托存储在字典中,其中参数的真实类型是它的关键字。因此,预期用法将始终确保始终使用正确类型的参数调用委托,并且不会发生运行时强制转换异常。