[F#][sharppcap][Error] «Экземпляр типа включает тип по ссылке». что такое обходной путь в F#

Я пытаюсь использовать SharpPcap в F#, но эта ошибка компилятора блокирует меня на два дня.

Я считаю, что наиболее актуальный ответ: Что такое ошибка «Создание экземпляра типа включает тип по ссылке». и что такое обходной путь в F#, но не подходит для моего контекста.

Пожалуйста, помогите мне обойти это, Спасибо!

open System
open SharpPcap
open SharpPcap.LibPcap

let device = new CaptureFileReaderDevice("test.pcap")

// try workaround 1
let new_package (sender: Object) (e: PacketCapture) = ()
let handler = new PacketArrivalEventHandler(new_package)
device.OnPacketArrival.AddHandler(handler)
// error: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.

// try workaround 2
let new_package (e: PacketCapture) = ()
device.OnPacketArrival.Add(new_package)
// error: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.

Я думаю, что ошибка в том, что:

public event PacketArrivalEventHandler OnPacketArrival;
public delegate void PacketArrivalEventHandler(object sender, PacketCapture e);
public readonly ref struct PacketCapture
{...}

Делегат PacketArrivalEventHandler использует PacketCapture в качестве типа параметра, но это readonly ref struct, который нельзя использовать для определения функции F# для добавления к событию OnPacketArrival.

Пожалуйста, помогите мне обойти это, спасибо!

Я хочу передать эту строку компилятору F#:

устройство.OnPacketArrival.Добавить (новый_пакет)

В С# он использовался таким образом:

устройство.OnPacketArrival += новый_пакет

[FS0412] При создании экземпляра типа используется тип по ссылке. Это не разрешено правилами Common IL.

Какую часть из вышеперечисленного вы можете изменить?

Fildor 31.01.2023 17:18

Пожалуйста, прочитайте нижний раздел этой страницы, а затем исправьте свой вопрос, отредактировав его: stackoverflow.com/help/tagged

ProgrammingLlama 31.01.2023 17:22

@Fildor Я хочу исправить эту ошибку компилятора этой строки device.OnPacketArrival.Add(new_package)

racer 31.01.2023 17:29

Я понял это. Но разрешено ли вам изменять код C# и F# или только одну из сторон?

Fildor 31.01.2023 18:06

@Fildor Я понимаю вашу точку зрения, я хочу изменить код F#, а не часть C#. Поскольку я думаю, что этот дизайн пакета C# хорош, проблема заключается в вызове функции C# со стороны F#.

racer 31.01.2023 18:13
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы не можете сделать это, используя первоклассные точки прослушивания F# IEvent, потому что в этом случае тип device.OnPacketArrival оказывается IEvent<PacketArrivalEventHandler, ref<PacketCapture>>, чей параметр второго типа ref<PacketCapture> не разрешен. Об этом сообщает сообщение об ошибке.

Но вы можете использовать базовые методы .NET add_ и remove_, которые являются аналогами методов свойства get_ и set_, но для событий. F# позволяет явно вызывать эти «скрытые» методы, даже если они не указаны в списках завершения IDE.

device.add_OnPacketArrival handler

Это работает, потому что он напрямую вызывает метод объекта device, а не создает значение-оболочку типа IEvent<...>, а затем вызывает для него .Add или .AddHandler.

Кстати, не могли бы вы сказать мне, где я могу получить эти знания: F# allows you to call these "hidden" methods explicitly, even though they're not listed in IDE completion lists.. Я искал в Google, чтобы попытаться решить мою проблему в течение двух дней, не нашел способа привести меня к этому ответу.

racer 31.01.2023 18:22

Мои знания об этих методах получены из изучения IL с помощью таких инструментов, как ILSpy и .NET Reflector (когда он был бесплатным), а затем подтверждены экспериментами. Я не знаю каких-либо конкретных мест в Интернете, где обсуждаются эти вещи. Возможно, спецификация C# или IL подойдет? Я почти уверен, что должен.

Fyodor Soikin 31.01.2023 18:29

Другие вопросы по теме