2016-04-18 3 views
3

私は以下のなかったF#で同じインターフェイスを実装する場合、FExceptionでIExceptionHandlerやIExceptionLoggerなどのメッセージハンドラを実装するときに「空のタスク」を返す正しい方法は何ですか? C#ので

type DefaultExceptionHandler() = 

    let mapExceptionTypetoHttpStatusCode (ex:Exception) : HttpStatusCode = 
     match ex with 
     | :? ArgumentException -> HttpStatusCode.BadRequest 
     | _ -> HttpStatusCode.InternalServerError 

    interface IExceptionHandler with 
     member x.HandleAsync (context:ExceptionHandlerContext, cancellationToken:CancellationToken) = 
      let request = context.Request 
      let ex = context.Exception 
      let httpStatusCode = mapExceptionTypetoHttpStatusCode ex 

      context.Result <- { new IHttpActionResult with member x.ExecuteAsync(token:CancellationToken) = Task.FromResult(request.CreateErrorResponse(httpStatusCode, ex)) } 
      Task.FromResult(0) :> Task 

コンパイラがどのキャストTask.FromResult(0) :> Taskを必要とした

public class DefaultExceptionHandler : IExceptionHandler 
{ 
    public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken) 
    { 
     context.Result = new ErrorActionResult(context.Request, context.Exception); 

     return Task.FromResult(0); 
    } 
} 

、私はこれに似た何かをするだろうこれらのハンドラを実装しますC#の例では必須ではありません。 F#のExecuteAsyncメソッドから返される正しい、慣用的な方法は何ですか?

答えて

4

F#コンパイラでは、F#ではスーパータイプ(またはそれ以外のもの)への自動変換がないため、キャストが必要です。これは、F#の非常に便利な機能です。スーパータイプへの変換がプログラムの意味を変えることになる間違いを防ぎます。

あなたのプログラムにこのキャスト演算子を使用することは、まったく問題ありません。あなたはあまりタイピングような気がしない場合は、あなたもあなたのための型を推論するために、コンパイラを求めることができます:

let a: obj = "abcd"   // No cast - compile-time error 
let b: obj = "abcd" :> obj // Explicit cast to supertype 
let c: obj = "abcd" :> _  // Explicit cast to inferred supertype 

あなたは本当にキャストを廃止する場合は、タスクの作成方法を使用することができますキャストする必要があるTask<T>ではなく、すぐにTaskを返します。

let t = Task.Run(fun() ->()) // t: Task 

しかし、これは方法より無駄である。このような方法の一つは、Task.Run(Action)です。

+0

ありがとうございます。私はそのままキャストでうまくいく。私はそれが適切で慣用的であることを確認したかったのです。私はベールに浸透するにつれ、F#が本当に好きです。 – pluralMonad

+0

コロンと角括弧を入力したくない場合は、 'upcast'演算子を使用することもできます。 –

関連する問題