F #: Могу ли я использовать try / with в конструкторе, который вызывает базовый класс? - PullRequest
2 голосов
/ 31 марта 2011

Я новичок в программировании на F #, и у меня возникли проблемы с правильным синтаксисом моей программы на F #.

По сути, я хочу превратить этот код C # в F #:

class MyRiskyObject : BaseObject
{
    private string field;

    public MyRiskyObject(object foo, string data)
        : base(foo)
    {
        try
        {
            this.data = RiskyOperation(data);
        }
        catch (ArgumentException)
        {
            DoSomethingElse();
        }
    }
}

У меня пока что есть что-то вроде

type MyRiskyObject
    inherit BaseObject

    val field : string

    new (foo:object, data:string) = {
        inherit BaseObject(foo)
        try
          field = RiskyOperation()
        ????????
    }

Я просто не могу понять синтаксис правильно ...

<ч />

Edit:

Вот фактический код, над которым я работаю:

type RegExpObject = 
  inherit CommonObject

  val RegExp : Regex
  val Global : bool

  member x.IgnoreCase:bool =
    (x.RegExp.Options &&& RegexOptions.IgnoreCase) = RegexOptions.IgnoreCase

  member x.MultiLine:bool =
    (x.RegExp.Options &&& RegexOptions.Multiline) = RegexOptions.Multiline

  new (env, pattern, options, global') =
    {
      inherit CommonObject(env, env.Maps.RegExp, env.Prototypes.RegExp) 

      // Here, I need to catch the exception, and instead call RaiseSyntaxError.
      RegExp = new Regex(pattern, options ||| RegexOptions.ECMAScript ||| RegexOptions.Compiled)

      Global = global'
    }
    then RegExp = new Regex(pattern, options ||| RegexOptions.ECMAScript ||| RegexOptions.Compiled)

  new (env, pattern) = 
    RegExpObject(env, pattern, RegexOptions.None, false)

Ответы [ 2 ]

2 голосов
/ 31 марта 2011

Почему бы просто не делегировать реальную работу отдельной свободной функции, чтобы работа не выполнялась непосредственно в конструкторе вашего класса?

let createRegex pattern options =
  try
    Regex(pattern, options ||| RegexOptions.ECMAScript ||| RegexOptions.Compiled)
  with
  | :? System.ArgumentException -> RaiseSynaxError ()

Затем ваш класс (как показано в вашемedit) будет:

type RegExpObject(env, pattern, options, global') //'
  inherit CommonObject(env, env.Maps.RegExp, env.Prototypes.RegExp)

  let RegExp = createRegex pattern options
  let Global = global' //'

  member x.IgnoreCase =
    (x.RegExp.Options &&& RegexOptions.IgnoreCase) = RegexOptions.IgnoreCase

  member x.MultiLine =
    (x.RegExp.Options &&& RegexOptions.Multiline) = RegexOptions.Multiline

  new (env, pattern) = RegExpObject(env, pattern, RegexOptions.None, false)

Преимущество здесь состоит в том, что, как указал @Brian, не нужно использовать val, что делает определение класса намного чище.

2 голосов
/ 31 марта 2011

Попробуйте следующее

type MyRiskyObject(foo : obj, data : string) as this =
    inherit BaseObject(foo)

    let mutable data = data;

    do
        try
            data <- this.RiskyOperation data 
        with 
            | :? System.ArgumentException -> this.DoSomethingElse()

Альтернативный пример с неизменяемой привязкой let, где RiskOperation и DoSomethingElse не являются членами MyRiskObject

type MyRiskyObject(foo : obj, data : string) =
    inherit BaseObject(foo)

    let data = 
        try 
           OtherModule.RiskyOperation data
        with
        | :? System.ArgumentException -> 
           OtherModule.DoSomethingElse()
           data
...