2016-01-03 11 views
5

私はF#ライブラリにアクセスするために使用するC#Web APIを持っています。返すタイプのDUを作成し、どのパターンマッチングを使用してC#コントローラに戻ってくるかを選択しました。C#でF#タイプを操作する

C#コントローラでは、関数呼び出しからF#ライブラリへの戻り値のデータにどのようにアクセスすればよいですか?

C#コントローラ

public HttpResponseMessage Post() 
{ 
    var _result = Authentication.GetAuthBehaviour(); 
    //Access item1 of my tuple 
    var _HTTPStatusCode = (HttpStatusCode)_result.item1; 
    //Access item2 of my tuple 
    var _body = (HttpStatusCode)_result.item2; 
    return base.Request.CreateResponse(_HTTPStatusCode, _body); 
} 

F#タイプ

module Types = 
    [<JsonObject(MemberSerialization=MemberSerialization.OptOut)>] 
    [<CLIMutable>] 
    type ValidResponse = { 
     odata: string; 
     token: string; 
    } 

    [<JsonObject(MemberSerialization=MemberSerialization.OptOut)>] 
    [<CLIMutable>] 
    type ErrorResponse = { 
     code: string; 
     message: string; 
     url: string; 
    } 

    type AuthenticationResponse = 
    | Valid of int * ValidResponse 
    | Error of int * ErrorResponse 

F#関数

module Authentication = 
    open Newtonsoft.Json 

    let GetAuthBehaviour() = 
     let behaviour = GetBehaviour.Value.authentication 
     match behaviour.statusCode with 
     | 200 -> 
      let deserializedAuthenticationResponse = JsonConvert.DeserializeObject<Types.ValidResponse>(behaviour.body) 
      Types.Valid (behaviour.statusCode, deserializedAuthenticationResponse) 
     | _ -> 
      let deserializedAuthenticationResponse = JsonConvert.DeserializeObject<Types.ErrorResponse>(behaviour.body) 
      Types.Error (behaviour.statusCode, deserializedAuthenticationResponse) 
+2

ここでは、C#で差別化されたユニオンを扱う方法の例があります。http://stackoverflow.com/questions/23843142/f-discriminated-union-usage-from-c-sharpまた、F#デザインガイドラインによれば、C#で利用可能なAPIから差別化された共用体を隠すことを検討すべきであることを示唆しています。 F#タプルは自動的に適切な 'Tuple <>'型のインスタンスに変換されるので、F#コードから3タプルを簡単に返すことができ、頭痛が少なくなります。 – jpe

答えて

5

F位識別型組合は、それぞれの場合、派生ネストされたクラスであると、抽象クラスとしてコンパイルされています。 C#のからは、GetAuthBehaviourから結果をダウンキャストを試みることによってケースにアクセスすることができます:C#コンパイラを使用すると、すべてのケースを扱ってきたことを知らないので、あなたが提供する必要がありますことを

public HttpResponseMessage Post() 
{ 
    var result = Authentication.GetAuthBehaviour(); 

    var valid = result as Types.AuthenticationResponse.Valid; 
    if (valid != null) 
    { 
     int statusCode = valid.Item1; 
     Types.ValidResponse body = valid.Item2; 
     return this.CreateResponse(statusCode, body); 
    } 

    var error = result as Types.AuthenticationResponse.Error; 
    if (error != null) 
    { 
     int statusCode = error.Item1; 
     Types.ErrorResponse body = error.Item2; 
     return this.CreateResponse(statusCode, body); 
    } 

    throw new InvalidOperationException("..."); 
} 

お知らせresultValidでもErrorでもない場合を処理するブランチです。ここでは例として例外を投げただけですが、Web APIでは500ステータスコードを返すほうが適切でしょう。

C#でコントローラを作成して管理するのに苦労しているのはなぜですか?あなたはwrite an ASP.NET Web API purely in F#です。