Вы правы - если вы хотите определить необязательные параметры для метода, вам нужно определить аргументы в форме с чередованием. Один из способов, с помощью которого вы могли бы приблизиться к этому, - переместить реализацию вашего метода Create
в частный метод (и переименовать его, например, на CreateImpl
), затем переопределить Create
как перегруженный метод, который просто отправит реализацию. Например:
type VAO =
{ Handle : int }
static member private CreateImpl (vboList, ibo : _ option) =
failwith "Not implemented."
static member Create vboList =
VAO.CreateImpl (vboList, None)
static member Create (vboList, ibo) =
VAO.CreateImpl (vboList, Some ibo)
Другой подход состоит в определении модуля (он должен быть помещен ниже определения вашего VAO
типа), который определяет кэрри функции, которые «окутывают» статический метод VBO.Create(...)
. Это будет работать, однако вы решите объявить аргументы для Create
(т. Е. Используя один метод с объявлением аргумента типа tuple и необязательными параметрами или используя описанный выше подход перегрузки). Например, если вы не используете мой метод перегрузки, и решили просто определить Create
, как static member Create (vboList, ?ibo)
:
// The [<CompilationRepresentation>] attribute is necessary here, because it allows us to
// define a module which has the same name as our type without upsetting the compiler.
// It does this by suffixing "Module" to the type name when the assembly is compiled.
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix>]
module VAO =
let create (vboList : _ list) =
VAO.Create vboList
let createWithIndex vboList ibo =
VAO.Create (vboList, ibo)
Эти функции модуля очень просты, так что это очень вероятно, что они будут встраиваемыми автоматически F # компилятор и вы не будете платить за это время. Если вы компилируете в режиме Release
, проверьте IL-ассамблею сборки и найдите, что это не так, тогда вы можете добавить ключевое слово inline
в определения функций, чтобы заставить их быть встроенными. (Лучше не делать силовую привязку, если вы не тестируете и не уверены, что она дает реальную прибыль.)
Один совет, не связанный с вашим вопросом о необязательных аргументах - рассмотрите переопределение по крайней мере некоторых из ваших типов в виде структур а не записи F #. Типы записей скомпилируются в классы (т. Е. Ссылочные типы), поэтому вы платите дополнительную стоимость косвенности без причины; определяя их как структуры, устранит эту косвенность и даст вашему приложению лучшую производительность. Еще лучше, если вы в состоянии, повторно использовать одну из существующих библиотек обертки OpenGL, например OpenTK или OpenGL4Net.
Просто примечание: в F # 4.1 модуль-суффикс больше не нужен, [подразумевается] (https://blogs.msdn.microsoft.com/dotnet/2016/07/25/a-peek- в-F-4-1 /). Кроме того, 4.1 [теперь поддерживает типы записей структуры) (https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/records), что упрощает достижение того, о чем говорится в вашем последнем комментарии. – Abel