Я выполнял маршалинг объектов в C# (считанных из потока двоичных файлов), которые написаны из неуправляемых структур C ++ с использованием C# функций взаимодействия COM . Моя цель состоит в том, чтобы сделать эти объекты доступными для привязки данных путем реализации интерфейса INotifyPropertyChanged .
Проблема заключается в том, что реализация INotifyPropertyChanged неизбежно сопровождается представлением события, измененного свойством, как класса publi c член. Службы маршаллинга распознают и обрабатывают его как 4-байтовый элемент структуры, тем самым изменяя двоичную структуру во время операций маршаллинга.
Это упрощенная c демонстрация проблемы. Рассмотрим эту C ++ struct :
struct Struct
{
int SomeMember; // example member
}
и эту C# адаптацию класса структуры:
[StructLayout(LayoutKind.Sequential)] // required for class marshalling
public class CppStruct
{
private int someMember; // encapsuled properties are recognized during marshalling
public int SomeMember { get => someMember; set => someMember = value; } // example member
}
и то же самое класс с реализованным интерфейсом INotifyPropertyChanged :
[StructLayout(LayoutKind.Sequential)] // required for class marshalling
public class CppStructNotifyPropertyChanged : INotifyPropertyChanged
{
private int someMember; // encapsuled properties are recognized during marshalling
public int SomeMember
{
get => someMember;
set
{
someMember = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SomeMember)));
}
}
public event PropertyChangedEventHandler PropertyChanged; // required by INotifyPropertyChanged implementation
}
Тогда System.Runtime.InteropServices.Marshal.SizeOf< CppStruct >()
дает 4 , что является правильным размером двоичного макета этой структуры, но System.Runtime.InteropServices.Marshal.SizeOf<
CppStructNotifyPropertyChanged
>()
дает 8 . Это показывает, что элемент PropertyChanged
автоматически обрабатывается как 4-байтовый тип.
Я пытался найти способ скрыть элемент события для маршалинга, но это просто не Кажется невозможным . Любое решение, связанное с наследованием , кажется неприменимым, так как события INotifyPropertyChanged охватывают все элементы, их необходимо вызывать для всех (включая базовый класс) элементов во время назначения. Я также думал о написании собственного сериализатора для класса, который игнорировал бы элемент события или вводил пользовательские атрибуты, позволяющие скрывать элементы, но для меня это наихудший вариант. Я хотел бы продолжать использовать функции маршаллинга по умолчанию, если это вообще возможно.
Есть ли способ достичь этого?
Стоит отметить, что у меня нет доступа и контроля над C ++ пишет и читает эти структуры, и я не вижу причины для этого. Наличие объекта события в любой форме в файле не имеет смысла. Также я использую. NET Framework 4.7.2 с Visual Studio 2017.