在C#中将委托转换为通用委托

时间:2016-10-02 20:13:29

标签: c# generics casting delegates

简介

我使用委托传递并存储单个表单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中找到相应的DictionaryButton依次应用(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

1 个答案:

答案 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;
}

乍一看,这似乎不是类型安全的,但在这种特殊情况下,它将是因为委托存储在字典中,其中参数的真实类型是它的关键字。因此,预期用法将始终确保始终使用正确类型的参数调用委托,并且不会发生运行时强制转换异常。