C# F#结构构造函数中的参数验证

C# F#结构构造函数中的参数验证,c#,f#,struct,c#-to-f#,C#,F#,Struct,C# To F#,下面是一个简单的C#结构,它对ctor参数进行一些验证: public struct Foo { public string Name { get; private set; } public Foo(string name) : this() { Contract.Requires<ArgumentException>(name.StartsWith("A")); Name = name; } }

下面是一个简单的C#结构,它对ctor参数进行一些验证:

public struct Foo
{
    public string Name { get; private set; }

    public Foo(string name)
        : this()
    {
        Contract.Requires<ArgumentException>(name.StartsWith("A"));
        Name = name;
    }
}
公共结构Foo
{
公共字符串名称{get;private set;}
公共Foo(字符串名称)
:此()
{
合同。要求和,但不包括参数验证

我哪里做错了?

您可以在初始化结构后使用
然后使用
块。在您的第一节中描述了在构造函数中执行副作用的类,但它也适用于结构

[]
类型Foo=
val名称:string
新建(名称:字符串)={name=name}
然后,如果name.StartsWith(“A”)则使用“Haiz”失败
更新:

另一种更接近示例的方法是使用
(顺序组合)和括号组合表达式:

[]
类型Foo=
val名称:string
新建(名称:字符串)=
{Name=((如果Name.StartsWith(“A”)那么failwith“Haiz”);Name)}

如果要避免显式字段(
val
)和
然后
,这两个相对深奥的功能,可以使用静态
创建
方法并坚持使用更常见的类型定义语法:

[]
键入Foo private(名称:string)=
成员x.名称=名称
静态成员创建(名称:字符串)=
合同要求(name.StartsWith“A”)
傅(姓名)

Ah,我曾尝试在{}中使用then。当这不起作用时,我认为这是因为它只能在类构造函数中使用(正如链接文章在该部分中所建议的那样)。当你说“不完全相同”时,这是因为验证发生在赋值之后吗?是的,对象是在抛出异常之前构造的。我从C#测试了您的示例,方法是在try/catch中调用
foo=new foo(“A”)
,然后在catch块中检查foo实例。我希望foo.Name等于“A”,但它是空的,即对象未被构造。在这种情况下,您的解决方案相当于C代码。太好了,感谢您提供的信息。我相应地更新了答案。很高兴了解该选项-我没有意识到您可以使用与类相同的语法定义结构(除了[]).然而,我不太喜欢创建方法-我更喜欢简单的ctor,因此会坚持学习val,然后再学习。