F # Друг функция / класс - PullRequest
       26

F # Друг функция / класс

3 голосов
/ 08 июля 2010

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

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

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

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

Ответы [ 4 ]

11 голосов
/ 08 июля 2010

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

Если вы хотите, чтобы 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 может видеть B.X, но продолжение программы не может видеть B.X.

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

3 голосов
/ 08 июля 2010

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

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

Работает угощение.

2 голосов
/ 08 июля 2010

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

1 голос
/ 08 июля 2010

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

...