在F#结构构造函数的参数验证 [英] Argument validation in F# struct constructor

查看:137
本文介绍了在F#结构构造函数的参数验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一个简单的C#结构,做的构造函数参数一些验证:

 公共结构美孚
{
公共字符串名称{;私人集; }

公共美孚(字符串名称)
:这()
{
Contract.Requires< ArgumentException的>(name.StartsWith(A));
名称=名称;
}
}



我已经成功地转化成F#类此





<预类=郎毫升prettyprint-覆盖> Foo类型(名称:字符串)=

Contract.Requires< ArgumentException的> (name.StartsWithA)
会员x.Name =名称



不过,我无法翻译这在F#的结构:



<预类=郎毫升prettyprint-覆盖> [<结构体>]
型美孚=
VAL名称:字符串
新(名称:字符串)= {做Contract.Requires< ArgumentException的> (name.StartsWithA);名称=名称}

这使编译错误:




无效的记录,序列或计算表达式。序列表达式应该是
形式的'序列{...}



这是不是有效的对象结构的表达。明确的对象的构造函数必须
或者调用一个可选的构造或初始化对象的所有字段,并指定
A调用父类的构造函数。




我看了一下但不包括参数验证。



我在哪里做错了?


解决方案


你可以使用<$ C初始化结构后,$ C>然后块。它的类在你第一次链接一节中构造的执行副作用说明< 。/ em>的,但它适用于结构以及



<预类=郎毫升prettyprint-覆盖> [<结构体>]
型美孚=
VAL名称:字符串
新(名称:字符串)= {名称=名称}
那么如果name.StartsWith(A),然后failwithHaiz

更新:



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



<预类=郎毫升prettyprint-覆盖> [<结构体>]
型美孚=
VAL名称:字符串
新(名称:字符串)=
{名称=((如果name.StartsWith(A),然后failwithHaiz);名)}


Here is a trivial C# struct that does some validation on the ctor argument:

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

    public Foo(string name)
        : this()
    {
        Contract.Requires<ArgumentException>(name.StartsWith("A"));
        Name = name;
    }
}

I've managed to translate this into an F# class:

type Foo(name : string) = 
    do 
        Contract.Requires<ArgumentException> (name.StartsWith "A")
    member x.Name = name

However, I can't translate this to a structure in F#:

[<Struct>]
type Foo = 
    val Name : string
    new(name : string) = { do Contract.Requires<ArgumentException> (name.StartsWith "A"); Name = name }

This gives compile errors:

Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq { ... }'

This is not a valid object construction expression. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor.

I've had a look at this and this but they do not cover argument validation.

Where am I doing wrong?

解决方案

You can use then block after initializing structs. It is described for classes in your first link in section Executing Side Effects in Constructors, but it works for structs as well.

[<Struct>]
type Foo = 
    val Name : string
    new(name : string) = { Name = name } 
                         then if name.StartsWith("A") then failwith "Haiz"

UPDATE:

Another way closer to your example is to use ; (sequential composition) and parentheses to combine expressions:

[<Struct>]
type Foo = 
    val Name : string
    new(name : string) = 
        { Name = ((if name.StartsWith("A") then failwith "Haiz"); name) } 

这篇关于在F#结构构造函数的参数验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆