#f#
#f#
Вопрос:
В F # тип записи, размещенный непосредственно в пространстве имен, будет скомпилирован как тип класса для C #.
e.g.,
namespace MyNameSpace
type MyType = { Name: string; Content: string; Text: string }
C # будет рассматривать MyType как статический общедоступный класс.
Но как C # видит MyType, когда он находится в модуле внутри пространства имен?
e.g.,
namespace MyNameSpace
module MyModule
type MyType = { Name: string; Content: string; Text: string }
Если он является закрытым для MyModule, может ли он быть общедоступным для C #?
(Я не смог найти этот ответ в Google : ( )
TIA
Ответ №1:
Модуль F # компилируется как класс. Если у вас есть объявление типа внутри модуля, оно будет скомпилировано как вложенный класс. В вашем примере MyNameSpace.MyModule.MyType
MyNameSpace
часть является пространством имен, но MyModule
(а также MyType
) являются классами.
В C # доступ к вложенным классам осуществляется с помощью .
, но на уровне CLR доступ к вложенному классу осуществляется с помощью
, поэтому, если вы хотите получить доступ, MyType
например, с помощью Type.GetType
, вам нужно использовать:
System.Type.GetType("MyNameSpace.MyModule MyType")
Обратите внимание, что это не работает в F # Interactive, который добавляет другое имя в пространство имен, но это работает в скомпилированном коде. Я не уверен, как это работает DataTemplate
в WPF, но, возможно, вам нужно указать тип, используя формат CLR с
в имени.
Ответ №2:
По умолчанию я полагаю, что все члены модуля будут следовать одной и той же общедоступной статической форме объявления. Результатом компиляции вашего примера здесь является легко доступный класс MyType из C#:
static void Main(string[] args)
{
var foo = new MyNameSpace.MyModule.MyType("x", "b", "c");
}
Чтобы принудительно контролировать доступ к элементу модуля, вам нужно немного изменить объявление:
module MySecrets =
type private SecretType = { Password: string }
РЕДАКТИРОВАТЬ: Ага, нашел соответствующую страницу:https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/access-control
Комментарии:
1. Я тоже так думал. Однако, когда MyType используется в DataTemplate WPF / C #, as DataType=»{x:Type vm:MyType}» работает с vm, являющимся указателем на пространство имен. Но, тип данных=»{x: Тип виртуальной машины:MyModule. MyType}» в среде CLR постоянно происходит сбой, сообщающий, что он не может найти MyType. Возможно, это связано с WPF CLR??? В любом случае, кажется, что он должен быть в пространстве имен.
2. Записи могут помещаться в модули и использоваться клиентами C #. Имя модуля является частью определенного пути при доступе к записи. Пример: откройте my_namespace_path.my_module.
3. @ScottNimrod Возможно, это так для клиентов C # — не так сильно для wpf / xaml. Кажется, что среда CLR просматривает только записи F # непосредственно в пространстве имен. Я не смог успешно разместить запись в модуле, который сам находится в пространстве имен : (
4. Я создаю мобильные приложения, используя F # с Xamarin. Forms, который также является XAML. Я думаю, что у вас другая проблема, с которой вы сталкиваетесь.
5. Рассматривали ли вы возможность использования статического импорта имени класса в вашем коде за файлами? Пример: использование статического mynamespece.mymodule