Search code examples
c#using-statement

hide implementation of C# 'using's arguments


I'm trying to abstract marshaling IntPtr to and from structs (actually class, so it's reference type) of data shared with native code.

I have this helper class:

class NativeStruct<StructType> : IDisposable
{
    public NativeStruct()
    {
        _DataPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(StructType)));
        Marshal.PtrToStructure(_DataPtr, _Data);
    }
    public NativeStruct(IntPtr dataPtr)
    {
        _DataPtr = dataPtr;
        Marshal.PtrToStructure(_DataPtr, _Data);
    }

    void IDisposable.Dispose()
    {
        Marshal.StructureToPtr(_Data, _DataPtr, true);
    }

    public StructType Data { get { return _Data; } }

    IntPtr _DataPtr;
    public StructType _Data;
}

Is there anyway to make this code implicit:

using (Shared_s data = new Toolbox.NativeStruct<DataStruct>(myIntPtr).Data)
{
    data.someMember = someValue;
}

Some way to change this to

EditStruct(DataStruct, myIntPtr)
{
    data.someMember = someValue;
}

In C++ I would have used a macro like

#define EditStruct(StructType, IntPtr) using  \
(Shared_s data = new Toolbox.NativeStruct<StructType>(IntPtr).data)

Solution

  • The closest thing you can do here is use lambda expressions:

    EditStruct<DataStruct>(myIntPtr, data =>
    {
        data.someMember = someValue;
    }); 
    

    Definition of EditStruct():

    void EditStruct<TStruct>(IntPtr dataPtr, Action<TStruct> action) 
         where TStruct : struct
    {
       using (var s = new Toolbox.NativeStruct<TStruct>(dataPtr))
       {
         action(s.Data);
       }
    }