好的做法 - 抛出异常以满足函数返回

Bob*_*way 3 c# error-handling return

构建了一个自定义IDataReader,它在XML中查找与特定元素名称匹配的值,如果找到,则返回值.GetValue函数 - 必须返回由接口指定的Object,如下所示:

    public object GetValue(int i)
    {
        string SearchString = _columns[i];

        var searchedAttributeValue = from nm in _el.Attributes(SearchString) select nm;
        if (searchedAttributeValue.Count() > 0)
        {
            return ParseTypes(searchedAttributeValue.First().Value);
        }

        var searchedElementValue = from nm in _el.Elements(SearchString) select nm;
        if (searchedElementValue.Count() > 0)
        {
            return ParseTypes(searchedElementValue.First().Value);
        }
    }
Run Code Online (Sandbox Code Playgroud)

显然,这不会构建,因为它可能在没有有效返回的情况下到达函数的末尾.

在这种情况下,如果发生这种情况,则意味着存在配置错误 - 用户正在寻找XML中不存在的元素或属性.

我发现(这对我来说是新的)你可以通过这样做解决问题:

    public object GetValue(int i)
    {
        if (_el == null)
        {
            _el = XNode.ReadFrom(_reader) as XElement;
        }
        string SearchString = _columns[i];

        var searchedAttributeValue = from nm in _el.Attributes(SearchString) select nm;
        if (searchedAttributeValue.Count() > 0)
        {
            return ParseTypes(searchedAttributeValue.First().Value);
        }

        var searchedElementValue = from nm in _el.Elements(SearchString) select nm;
        if (searchedElementValue.Count() > 0)
        {
            return ParseTypes(searchedElementValue.First().Value);
        }

        throw new Exception("oh crap!");
    }
Run Code Online (Sandbox Code Playgroud)

所以函数不返回,它只是抛出一个错误.

但是,这种方法存在根本性的错误.没关系,为什么它没关系/不好,是否有更好的方法来处理这种情况?

Jon*_*eet 6

好吧,除非你真的需要catch块,你并不需要引入的try/catch /最后.您可以throw在初始方法的末尾添加一个语句.

一路上,我开始使用FirstOrDefault(),遵循常规C#命名约定的局部变量,当它们不是非常有用时停止使用查询表达式,并抛出一个更具体的异常:

public object GetValue(int i)
{
    string searchString = _columns[i];

    var searchedAttribute = _el.Attributes(searchString).FirstOrDefault();
    if (searchedAttribute != null)
    {
        return ParseTypes(searchedAttribute.Value);
    }

    var searchedElement = _el.Elements(searchString).FirstOrDefault();
    if (searchedElement != null)
    {
        return ParseTypes(searchedElement.Value);
    }
    // Nothing found - oops.
    throw new SomeSpecificException("Some message here");
}
Run Code Online (Sandbox Code Playgroud)

如果您需要catch块进行日志记录,我可能会尝试捕获一个特定的异常,这可能意味着将其移动到ParseTypes任何位置(因为您不应该从其余的调用中获得任何异常...)无论哪种方式,请保持最后的throw声明.

编辑:在设计方面,是否应该在未找到值时抛出异常,或者实际上取决于期望值.我们无法知道这是否表明系统出现了问题,或者只是完全正常的数据缺失.这应该决定你的选择.特别是,如果每个调用者都试图捕获异常,那么这就是设计气味,你应该返回null或使用类似Dictionary<,>.TryGetValue方法的东西.