处理重复代码和异常的更好方法

时间:2016-11-14 08:53:37

标签: c# exception exception-handling

给出以下代码:

_samedayServiceDescription = com_SubServiceDescriptionExtDS.COM_SubServiceDescriptionExt.Where(r => r.Description.Equals(samedayService)).First().ServiceSubServiceId;
_onedayServiceDescription = com_SubServiceDescriptionExtDS.COM_SubServiceDescriptionExt.Where(r => r.Description.Equals(onedayService)).First().ServiceSubServiceId;
_datedServiceDescription = com_SubServiceDescriptionExtDS.COM_SubServiceDescriptionExt.Where(r => r.Description.Equals(datedService)).First().ServiceSubServiceId;
_unpaidServiceDescription = com_SubServiceDescriptionExtDS.COM_SubServiceDescriptionExt.Where(r => r.Description.Equals(unpaidService)).First().ServiceSubServiceId;
_recallServiceDescription = com_SubServiceDescriptionExtDS.COM_SubServiceDescriptionExt.Where(r => r.Description.Equals(recallService)).First().ServiceSubServiceId;

如果我期望的项目不存在,我可以在每个First()调用上获得异常,如果缺少配置中的某些内容,则可能是这种情况。我希望能够在运行时告诉哪一个抛出异常来提供信息性的消息来说出“嘿,你的配置缺少x的服务”。

我能想到这样做的唯一方法是在每一行周围放置一个try / catch块。当然有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

如果你可以使用C#6功能,你可以这样做。首先定义通用扩展方法:

 public static class Extensions {
    public static T ThrowIfNull<T>(this T value, string msg) {
        if (value == null) {
            throw new Exception(msg);
        }
        return value;
    }
}

然后

_samedayServiceDescription = (com_SubServiceDescriptionExtDS.COM_SubServiceDescriptionExt
    .FirstOrDefault(r => r.Description.Equals(samedayService))?.ServiceSubServiceId)
    .ThrowIfNull("hey, your configuration is missing the service for x");

请注意,如果您的ServiceSubServiceId是结构(如int),则整个表达式的结果将为int?,而您可能希望它仍然是常规int 。在这种情况下,您可以使用这种扩展方法:

public static T ThrowIfNull<T>(this T? value, string msg) where T : struct {
    if (!value.HasValue) {
        throw new Exception(msg);
    }
    return value.Value;
}

你可以同时使用两种扩展方法,然后选择第二种扩展方法,其余的 - 第一种方法。

答案 1 :(得分:0)

使用FirstOrDefault()

_samedayServiceDescription = com_SubServiceDescriptionExtDS.COM_SubServiceDescriptionExt.Where(r => r.Description.Equals(samedayService)).FirstOrDefault().ServiceSubServiceId;
_onedayServiceDescription = com_SubServiceDescriptionExtDS.COM_SubServiceDescriptionExt.Where(r => r.Description.Equals(onedayService)).FirstOrDefault().ServiceSubServiceId;
_datedServiceDescription = com_SubServiceDescriptionExtDS.COM_SubServiceDescriptionExt.Where(r => r.Description.Equals(datedService)).FirstOrDefault().ServiceSubServiceId;
_unpaidServiceDescription = com_SubServiceDescriptionExtDS.COM_SubServiceDescriptionExt.Where(r => r.Description.Equals(unpaidService)).FirstOrDefault().ServiceSubServiceId;
_recallServiceDescription = com_SubServiceDescriptionExtDS.COM_SubServiceDescriptionExt.Where(r => r.Description.Equals(recallService)).FirstOrDefault().ServiceSubServiceId;

然后为每个处理空值。您也可以在结尾处使用??并进行初始化。很干净。像这样:

(com_SubServiceDescriptionExtDS.COM_SubServiceDescriptionExt.Where(r => r.Description.Equals(recallService)).FirstOrDefault()??new Type()).ServiceSubServiceId;