F#`try`-`with`块内的转换和异常过滤器

时间:2014-01-08 13:16:42

标签: c# exception-handling f# c#-to-f#

我正在尝试将这段C#转换为F#:

var webClient = new WebClient();
try {
    webClient.DownloadString (url);
} catch (WebException e) {
    var response = e.Response as HttpWebResponse;
    if (response == null)
        throw;
    using (response) {
        using (Stream data = response.GetResponseStream ()) {
            string text = new StreamReader (data).ReadToEnd ();
            throw new Exception (response.StatusCode + ": " + text);
        }
    }
}

我现在已经想出了这个,但它没有编译,因为我无法在块中使用letuse显然:

let Download(url: string) =
    use webClient = new WebClient ()
    try
        webClient.DownloadString(url)
    with
        | :? WebException as ex when ex.Response :? HttpWebResponse ->
             use response = ex.Response :?> HttpWebResponse
             use data = response.GetResponseStream()
             let text = new StreamReader (data).ReadToEnd ()
             failwith response.StatusCode + ": " + text

1 个答案:

答案 0 :(得分:7)

稍微分解一下并使用括号会对你有所帮助:

let download (url : string) = 
    use webClient = new WebClient()
    try
        webClient.DownloadString(url)
    with
        | :? WebException as ex when (ex.Response :? HttpWebResponse) ->
             use response = ex.Response :?> HttpWebResponse
             use data = response.GetResponseStream()
             use reader = new StreamReader(data)
             let text = reader.ReadToEnd()
             failwith (response.StatusCode.ToString() + ": " + text)

此功能可按预期编译和工作。

我不是专家,但是如果我不得不猜测我会说when之后的表达必须在括号中以强制执行正确的评估顺序(所以首先检查类型,然后{{ 1}}它),不是严格从左到右。

对于when也是如此,因为要首先评估字符串连接,它应该在括号中。