如何使用F#中字符串列表类型的auto属性声明类?

如何使用F#中字符串列表类型的auto属性声明类?,f#,c#-to-f#,F#,C# To F#,我很难理解如何在F#中定义类,在F#中我有属性,但没有声明值。相当于c代码的东西: 类实体 { 公共字符串名称{get;set;} 公共列表收藏夹{get;set;} } 我只能用定义的类型声明类型,如 type Entity = member val Name = "" with get, set 当我指定null时,名称的类型将为null。如注释中所述,null值不建议在F#中使用,因此如果可以,最好避免使用它们。默认情况下,F#类型也不允许null,因此如果您使用的是不可变的

我很难理解如何在F#中定义类,在F#中我有属性,但没有声明值。相当于c代码的东西:

类实体
{
公共字符串名称{get;set;}
公共列表收藏夹{get;set;}
}
我只能用定义的类型声明类型,如

type Entity = 
    member val Name = "" with get, set

当我指定null时,名称的类型将为null。

如注释中所述,
null
值不建议在F#中使用,因此如果可以,最好避免使用它们。默认情况下,F#类型也不允许
null
,因此如果您使用的是不可变的F#
list
type,那么最好的选择是将属性初始化为空列表:

type Entity() = 
    member val Name = "" with get, set
    member val Favorities : list<string> = [] with get, set
我想如果您使用的是一些非F友好的ORM和类似的东西,这可能会很有用,但否则,使用它可能会给您带来很多痛苦和意外错误。

与该C代码最接近的F代码是:

type Entity() = 
    member val Name = Unchecked.defaultof<string> with get, set
    member val Favorites = Unchecked.defaultof<string list> with get, set
或者,您应该使用
选项
类型显式选择值,并使用
作为默认值,以避免运行时出现空引用异常:

type Entity() = 
    member val Name = None : string option with get, set
    member val Favorites = None : string list option with get, set

注意:我上面使用的
列表
与C#
列表
不同,我在您的评论中看到,您使用
成员val
的原因是针对Newtonsoft.Json的。将它与F#记录一起使用曾经是一个问题,但现在它工作得非常好。使用Newtonsoft.Json 10.0.3测试了以下内容:

type Foo =
    {
        x: int
        y: float
    }

open Newtonsoft.Json

let foo = JsonConvert.DeserializeObject<Foo>("{\"x\":1,\"y\":1.2}")
printfn "%A" foo
// {x = 1;
//  y = 1.2;}
输入Foo=
{
x:int
y:浮子
}
打开Newtonsoft.Json
让foo=JsonConvert.DeserializeObject(“{\'x\':1,\'y\':1.2}”)
printfn“%A”foo
//{x=1;
//y=1.2;}

对于需要默认构造函数和可变字段的序列化库,您可以将
[]
属性放在记录上,它将提供这些属性(但从F#不可见,以保证安全)。

F#不喜欢空值。这是它最大的优点之一。如果值为空,则偶数ORMs返回
字符串选项
。使用
选项。改为“无”
。您是否尝试过
成员val名称:string=null with get,set
成员val收藏夹:ResizeArray=null with get,set
?不清楚您在问什么。问题是关于null还是字符串列表?或者两者都有?另外,
null
不是一种类型。很抱歉,我不够精确。我有点困惑,因为我创建的类将被另一个库使用。以前它是用c写的。这就是为什么我想知道,当某些属性为null或空值时,是否存在一些特殊的逻辑。如果列表无值或为空,则与列表相同。谢谢您的回答。我喜欢F#尝试不使用空值,但在.net framework环境中很难完全停止。是的。。。您是对的,它看起来非常难看,但当您使用Newtonsoft库反序列化json时,什么是最好的选择?它们不会处理记录或元组。在我的例子中,我将使用默认值,看看会发生什么。谢谢
type Entity() = 
    member val Name = None : string option with get, set
    member val Favorites = None : string list option with get, set
type Foo =
    {
        x: int
        y: float
    }

open Newtonsoft.Json

let foo = JsonConvert.DeserializeObject<Foo>("{\"x\":1,\"y\":1.2}")
printfn "%A" foo
// {x = 1;
//  y = 1.2;}