当前位置:  开发笔记 > 编程语言 > 正文

在C#中使用F#类型

如何解决《在C#中使用F#类型》经验,为你挑选了1个好方法。

我有一个C#web api用于访问F#库.我创建了一个我想要返回的类型的DU,并使用模式匹配来选择哪个返回到c#控制器.

在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 =
    []
    []
    type ValidResponse = {
         odata: string;
         token: string; 
    }

    []
    []
    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(behaviour.body)
            Types.Valid (behaviour.statusCode, deserializedAuthenticationResponse)
        | _ ->
            let deserializedAuthenticationResponse = JsonConvert.DeserializeObject(behaviour.body)
            Types.Error (behaviour.statusCode, deserializedAuthenticationResponse)

Mark Seemann.. 5

F#Discriminated Unions被编译为抽象类,每个case都是派生的嵌套类.从C#,您可以通过尝试向下转换结果来访问案例GetAuthBehaviour:

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("...");
}

请注意,C#编译器不知道您已经处理了所有情况,因此您需要提供一个分支来处理result既不是Valid也不是的情况Error.在这里,我简单地抛出异常作为示例,但在Web API中,返回500状态代码可能更合适.

但是,所有这些都说明了为什么在C#中编写和维护控制器的麻烦呢?您可以完全用F#编写ASP.NET Web API.



1> Mark Seemann..:

F#Discriminated Unions被编译为抽象类,每个case都是派生的嵌套类.从C#,您可以通过尝试向下转换结果来访问案例GetAuthBehaviour:

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("...");
}

请注意,C#编译器不知道您已经处理了所有情况,因此您需要提供一个分支来处理result既不是Valid也不是的情况Error.在这里,我简单地抛出异常作为示例,但在Web API中,返回500状态代码可能更合适.

但是,所有这些都说明了为什么在C#中编写和维护控制器的麻烦呢?您可以完全用F#编写ASP.NET Web API.

推荐阅读
携手相约幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有