F#Generic List将方法保存为方法参数...如何在Abstract Type上编写方法签名

时间:2011-11-10 14:49:53

标签: generics f#

试图弄清楚如何创建一个方法列表中的方法和另一个参数。我有我在C#中创建的方法,我正在尝试将其转移到F#:

public interface IValidator
{
    MethodResult Validate(IList<Func<userModel, MethodResult>> validationMethods
      , userModeltoValidate);
}

我尝试过类似的事情:

type public IValidator =
  abstract Validate : IList<(BasicUserModel -> MethodResult<'a>)>, BasicUserModel 
    -> MethodResult<'a>

但即使我用括号括起参数签名,它也不喜欢语法。最终目标是拥有一个方法,该方法接收方法列表并通过迭代列表来运行它们。

public MethodResult Validate(IList<Func<BasicUserModel, MethodResult>> validationMethods, 
   BasicUserModel toValidate)
{
   ...
}

循环部分我可以轻松使用F#,它是抽象类型和实现杀死我的方法的类型的方法签名语法。

2 个答案:

答案 0 :(得分:1)

F#相当于

public MethodResult Validate(
   IList<Func<BasicUserModel, MethodResult>> validationMethods, 
   BasicUserModel toValidate) {
   ...
}

member this.Validate
   (validationMethods : IList<(BasicUserModel -> MethodResult)>, 
    toValidate : BasicUserModel) = ...

唯一的区别是F#版本需要IList的{​​{1}}(更加惯用)与C#中的FSharpFunc

答案 1 :(得分:1)

在抽象方法声明中,不是用逗号分隔参数类型,而应该用星号分隔,就像方法采用元组一样:

abstract Validate : IList<(BasicUserModel -> MethodResult<'a>)> * BasicUserModel 
                         -> MethodResult<'a>  

以下是其他一些想法:

  1. 默认情况下,类型是公开的,因此您可以在类型声明中省略public关键字。
  2. 除非您可能需要随机访问而不是循环,否则获取seq<_>而不是IList<_>会更加惯用(并且对于来电者更灵活)。
  3. 我认为这是故意的,但是你的F#validate方法将是通用的(因为它使用未声明的类型参数MethodResult<'a>返回'a)。如果要在泛型类型上使用非泛型方法,请将'a参数添加到类型声明中:type IValidator<'a> = ...