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

kno*_*cte 4 c# f# exception-handling 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我现在已经想出了这个,但是它没有编译,因为我显然不能使用let或者usewith块中:

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
Run Code Online (Sandbox Code Playgroud)

Pat*_*iek 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)
Run Code Online (Sandbox Code Playgroud)

此函数按预期编译和工作.

我不是专家,但如果我不得不猜测我会说后面的表达式when必须在括号中强制执行正确的评估顺序(所以先键入检查,然后再检查when),而不是严格从左到右.

同样的事情是failwith,首先要对字符串连接进行评估,它应该在括号中.

  • @ 7sharp9:我没有看到任何皱眉.这正是打算使用反向管道的方式. (3认同)
  • 'failwithf"%O:%s"response.StatusCode text' (2认同)