泛型可以使用吗?

时间:2012-01-06 17:44:19

标签: c# generics

我的代码中至少有10次不同的代码。看起来有点臭我。

        public void DisplayTransitInfo(TransitInfo transitInfo)
    {
        if (InvokeRequired)
            EndInvoke(BeginInvoke(new MethodInvoker(() => DisplayTransitInfo(transitInfo))));
        else
        {
            var control = (from string key in _visiblePanes.Keys
                           where key == "transitInfo"
                           select _visiblePanes[key].Control).ToList();

            TransitInfoControl cntl = (TransitInfoControl)control[0];
            //TODO: Transit Info
        }
    }

    public void ModifyParties(UltraTreeNode node)
    {
        if (InvokeRequired)
            EndInvoke(BeginInvoke(new MethodInvoker(() => ModifyParties(node))));
        else
        {
            var control = (from string key in _visiblePanes.Keys
                           where key == "parties"
                           select _visiblePanes[key].Control).ToList();

            PartiesControl cntl = (PartiesControl)control[0];
            cntl.ModifyParties(node);
        }
    }

我觉得在这种情况下可以使用泛型。我也考虑过搬家:

                var control = (from string key in _visiblePanes.Keys
                           where key == "parties"
                           select _visiblePanes[key].Control).ToList();

到它自己的函数,它将返回字典中控件的实例。

这段代码是否有问题,或者我只是需要让我的鼻子工作?

一如既往地谢谢!

3 个答案:

答案 0 :(得分:3)

如果您在应用程序中使用相同的代码10次,则绝对重构时间!

为什么要写

 (from string key in _visiblePanes.Keys
                       where key == "parties"
                       select _visiblePanes[key].Control)

当您可以使用_visiblePanes["parties"]时(如果您不确定密钥是否存在,请使用TryGetValue

为什么control列表? control听起来不像集合的名称。

答案 1 :(得分:3)

如果您想简化

        var control = (from string key in _visiblePanes.Keys  
                       where key == "transitInfo"  
                       select _visiblePanes[key].Control).ToList();  

        TransitInfoControl cntl = (TransitInfoControl)control[0]; 

        var control = (from string key in _visiblePanes.Keys   
                       where key == "parties"   
                       select _visiblePanes[key].Control).ToList();   

        PartiesControl cntl = (PartiesControl)control[0];   

如果_visiblePanes是一个字典,这意味着它可以没有重复的键,那么你不需要泛型,只需使用它:

var cntl = (TransitInfoControl)_visiblePanes["transitInfo"].Control;

var cntl = (PartiesControl)_visiblePanes["parties"].Control;

修改

(在上面添加了强制转换以与原始代码等效)

与Jim Mischel相比,这个建议不仅更易于输入和读取,而且更接近原始代码,因为如果字典中没有键,它会抛出异常。如果原始代码使用Linq试图涵盖这种可能性,则它会在PartiesControl cntl = (PartiesControl)control[0];失败。假设字典中没有键是非常例的,那么,当然,Jim的TryGetValue解决方案更好。

要回到关于泛型的原始问题, 在将获取和转换逻辑提取到泛型方法中是一个可能的优势:

bool TryGetCast<T>(IDictionary<string, BaseControl> dict, string key, out T value) where T : BaseControl
{
    BaseControl tryGet;
    if (dict.TryGetValue(key, out tryGet)
    {
        value = (T)tryGet;
        return true;
    }
    value = default(T);
    return false;
}

可以这样称呼:

PartiesControl cntl;
if (TryGetCast(_visiblePanes, "parties", out cntl))
{
    //do whatever;
}

但是,好处很小。吉姆的解决方案加上演员阵容并不那么冗长:

BaseControl c; 
if (_visiblePanes.TryGetValue("parties", out c)) 
{
    var cntl = (PartiesControl)c;
    // do whatever
}

答案 2 :(得分:2)

我可能会遗漏一些东西,但在我看来,你可以摆脱那里的整个LINQ表达式。也就是说,这段代码:

 var control = (from string key in _visiblePanes.Keys
                where key == "parties"
                select _visiblePanes[key].Control).ToList();
 PartiesControl cntl = (PartiesControl)control[0];

如果我正确地阅读,那么您将枚举一个键控集合,以查找具有关键“派对”的所有项目。但是既然你写了_visiblePanes[key].Control,似乎只有其中一个。我将假设_visiblePanesDictionary<string, BaseControl>,其中BaseControl是任何类PartiesControl,而您的其他控件类型继承自。{/ p>

BaseControl cntl;
if (_visiblePanes.TryGetValue("parties", out cntl))
{
    PartiesControl pcntl = cntl as PartiesControl;
    // do whatever
}