Для простых случаев я также предложил бы смотреть XmlOutput быстрый интерфейс для создания Xml.
XmlOutput является большим для простого создания Xml с читаемым и удобным в сопровождении кодом при генерации допустимого Xml. сообщение orginal имеет некоторые яркие примеры.
Каждый из остальных ответов пока частично отражает картину ...
type Foo<'a> private() = // '
static member Blah (a:'a) = // '
printfn "%A" a
великолепно. Не обращайте внимания на то, что генерирует Reflector, вы не можете создать экземпляр этого класса из сборки F # (поскольку конструктор является частным), поэтому это хорошо работает.
F # также допускает статические конструкторы, синтаксис должен включать 'static let' и ' статические операторы do 'в классе (которые работают аналогично тому, как' let 'и' do 'работают как часть тела основного конструктора для экземпляров). Полный пример:
type Foo<'a> private() = // '
static let x = 0
static do printfn "Static constructor: %d" x
static member Blah (a:'a) = // '
printfn "%A" a
//let r = new Foo<int>() // illegal
printfn "Here we go!"
Foo<int>.Blah 42
Foo<string>.Blah "hi"
Сначала я подумал, что это будет близко к тому, что вы хотели:
type Foo<'a> private() =
static member Blah (a:'a) =
printfn "%A" a
Быть похожим на идиому до C # 2.0: создание экземпляров только через отражение или самим классом (что, надеюсь, не t сделать это).
однако это скомпилировано до:
[Serializable, CompilationMapping(SourceConstructFlags.ObjectType)]
public class Foo<a>
{
internal Foo() {...}
public static void Blah(a a) {...}
}
, что означает, что другие классы в сборке f # могут создать его экземпляр.
Однако когда-либо проинформированный Брайан указал, что компилятор f # уважает эту частную настройку, несмотря на базовый тип CLR, что означает, что единственный способ создать экземпляр будет через отражение или использование чего-то вроде атрибута InternalsVisibleTo.
Это все еще может быть быть приемлемым для ваших нужд ...