Контекст этого вопроса - raytracer, который я пишу.
У меня есть тип Surface, в идеале мне нужен абстрактный базовый класс, от которого наследуются NoSurface и Lambertian.
Однако, когда у меня есть эта иерархия, у меня возникает следующая проблема:
let closestIntersection : bool*LineParameter*Surface =
match allIntersectionsWithRealSolutions with
| [] -> (false,0.0f, NoSurface(0UL,NotHitable(),Material(Vector3.Zero)))
| x::xs -> List.reduce (fun smallest current -> smallestIntersection smallest current) allIntersectionsWithRealSolutions
Это выдает ошибку компилятора , поскольку тип, с которым он связывает возвращаемый тип, - NoSurface,даже при указании типа в качестве Surface.
Это решило проблему:
let closestIntersection : bool*LineParameter*Surface =
match allIntersectionsWithRealSolutions with
| [] -> (false,0.0f, NoSurface(0UL,NotHitable(),Material(Vector3.Zero)) :> Surface)
| x::xs -> List.reduce (fun smallest current -> smallestIntersection smallest current) allIntersectionsWithRealSolutions
closestIntersection
Но приведение :>
стоит мне 25 мс согласно BenchmarkDotNet по сравнению с решением определения Surface как (не абстрактный) класс и просто возвращает его вместо этого!
Могу ли я как-то избежать явного приведения и иметь желаемую иерархию Существа Поверхности и абстрактного класса?