Создайте объект в C # из объекта F # с необязательными аргументами - PullRequest
6 голосов
/ 01 мая 2010

У меня есть объект в F # следующим образом ...

type Person(?name : string) = 
    let name = defaultArg name ""
    member x.Name = name

Я хочу иметь возможность создать экземпляр этого объекта в проекте C #. Я добавил в качестве ссылки правильные библиотеки в проект и могу видеть объект через intellisense, однако я не уверен в правильном синтаксисе для создания экземпляра объекта.

В настоящее время в моем проекте на C # есть следующее - что не нравится компилятору ...

var myObj1 = new Person("mark");            

Ответы [ 4 ]

9 голосов
/ 01 мая 2010

Вы можете быть счастливее, просто предоставив две перегрузки конструктора:

type Person(name : string) =  
    new() = Person("")
    member x.Name = name 

Тогда это будет хорошо работать как с F #, так и с C #.

9 голосов
/ 01 мая 2010

Чтобы добавить некоторые детали, компилятор F # использует другой подход для представления необязательных параметров, который (в настоящее время) не совместим с подходом C # 4.0. F # просто позволяет вам использовать более приятный синтаксис, когда параметр имеет тип option<'a> (и помечен как необязательный). Вы можете использовать его как есть или использовать функцию defaultArg для предоставления значения по умолчанию в вашем коде .

В C # параметр специально представлен в метаданных (особенность .NET 4.0), а значение по умолчанию указано в метаданных . К сожалению, в F # невозможно создать совместимый с C # 4.0 необязательный параметр.

Если вы хотите сделать код C # немного более приятным, вы можете определить статический служебный класс, который позволит вам использовать вывод типов при создании значений option<'a>:

static class FSharpOption {
  static FSharpOption<T> Some<T>(T value) {
    return new FSharpOption<T>(value);
  }
}

// Then you can write just:
var myObj1 = new Person(FSharpOption.Some("mark")); 

Или вы можете изменить объявление F # для использования перегруженных методов / конструкторов, которые работают на обоих языках:

type Person(name) = 
  do printfn "%s" name
  // Add overloaded constructor with default value of name'
  new () = Person("")
5 голосов
/ 01 мая 2010

Необязательные аргументы работают в F # иначе, чем в C #, поэтому я считаю, что вам нужно будет эмулировать подход F # в вашем коде C #:

var myObj1 = new Person(new FSharpOption<string>("mark"));
0 голосов
/ 05 сентября 2013

Вы можете создать класс Person с F # -совместимыми и C # -совместимыми необязательными аргументами конструктора, например:

// F#-compatible ctor with optional args
type Person(?name, ?dummy) = 
    let name = defaultArg name ""

    // C#-compatible ctor with optional arg
    new([<Optional; DefaultParameterValue "">] name) = 
        Person(name, null)

    member x.Name = name

Маурисио Шеффер расширил эту тему здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...