2010-07-08 4 views
3

Возможно ли реализовать функцию друга и класс друга (как в C++) в F #?F # Функция друга/класс

Update: Поскольку нет друга функции/класса в F #, и друг даже не зарезервированное ключевым слова для будущего расширения, я задаюсь вопросом, есть ли какие-либо проблемы с механизмом друга в F #, которые делают разработчик решить не выполнять его? (such as in "protected" access modifier).

Предложение 1: Brian, файл подписи - Не думаю, что эта штука работает правильно. Если у вас есть замыкание (например, лямбда-выражение в A, который представляет собой другой объект, чем экземпляр A), которые оценивают BX, это не будет работать

Предложение 2: горный массив (+ Mitya0), InternalsVisibleTo - Мне непонятно, вы пишете это во втором классе или выставляете класс для всей сборки?

+0

Вы имеете в виду «друга», как в C++, или как в VB.NET? –

ответ

11

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

Если вы хотите A быть другим B, так A может получить доступ к внутренности B, что другие не могут видеть, что вы можете сделать, например,

// File1.fs 
type B() = 
    let x = 42 // private field 
    member this.X = x // public getter 

type A() = 
    member this.PeekInto(b : B) = 
     b.X 

но также

// File1.fsi 
type B = 
    new : unit -> B 
    // do not expose X in the signature 

type A = 
    new : unit -> A 
    PeekInto : B -> int 

и теперь A «s реализация может увидеть B.X но продолжение программы не могут видеть B.X.

Файлы подписи являются довольно удивительными для создания произвольных границ инкапсуляции.

+0

Мне нравится это решение! –

+0

Я тоже - файлы подписи - одна из самых удивительных особенностей языка, о которых никто не знает (см. Http: // stackoverflow.com/questions/181613/hidden-features-of-f/1844881 # 1844881) – Brian

+0

Да - прискорбно, что границы видимости, которые накладываются подписи, в настоящее время жестко совпадают с границами файлов –

2

Концепция друзей, как она существует в C++, не совсем переводится на F #, но вы можете использовать модификатор доступности internal, чтобы разрешить доступ ко всем классам в той же сборке .NET. Вероятно, это то, что вы ищете.

+0

'internal' является тупым инструментом, пользуйтесь им с осторожностью. – Brian

+0

Внутренний только тупой, если ваши сборки большие. –

+0

@ Митя, да, к сожалению, границы видимости, которые «внутренние» накладывают, жестко совпадают с границами сборки. : P – Brian

1

Из того, что я вижу в документации, есть friend notion in C#,, но такая же документация предполагает, что F # не обладает этой способностью.

+4

Все в документации, которую вы цитируете, относится к F #, включая InternalsVisibleTo атрибут –

3

Как указал Митя. Просто используйте атрибут InternalsVisibleTo для класса, в котором вы хотите видеть защищенные члены, или на всей сборке. (Я делаю это все время для тестирования модулей).

[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("UnitTestModule")>] 

Работы по уходу.

Смежные вопросы