Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Workaround to add a default parameterless constructor to a struct

Let me describe my problem - I have a struct that wraps an unmanaged handle (let's call it Mem). I need this handle to call a particular method (say "retain" or alternatively, maintain a reference count) whenever it is copied.

In other words, I need a struct that maintains a reference count internally (I have a mechanism externally as well, but need a way to invoke that mechanism).

Unfortunately, C# doesn't let me do this in any way.

I also cannot make Mem a class because I will pass an array of these structs to unmanaged code and I do NOT want to convert them one by one before passing them in (just pin and pass).

Does anyone know of any workaround (IL Weaving, etc) that can be applied to add this behavior in? I believe IL doesn't prevent me from doing this, only C#, correct?

I am happy to answer any questions about the framework and restrictions I have, but I am not looking for - "please change your design" or "don't use C# for this" answers, thanks very much.

like image 277
Ani Avatar asked Feb 11 '26 13:02

Ani


2 Answers

I believe IL doesn't prevent me from doing this, only C#, correct?

Yes, that's right where "this" is "a parameterless constructor for a struct". I blogged about that a while ago.

However, having a parameterless constructor does not do what you want in terms of notifying you every time a struct is copied. There's basically no way of doing that, as far as I'm aware. The constructor isn't even called in every case when you end up with a "default" value, and even if it were, it's certainly not called just for copy operations.

I know you don't want to hear "please change your design" but you're simply asking for something which does not exist in .NET.

I would suggest having some sort of method on the value type which returns a new copy, having taken appropriate action. You then need to make sure you always call that method at the right time. There will be nothing preventing you from getting this wrong, other than whatever testing you can build.

like image 96
Jon Skeet Avatar answered Feb 13 '26 01:02

Jon Skeet


Does anyone know of any workaround (IL Weaving, etc) that can be applied to add this behavior in? I believe IL doesn't prevent me from doing this, only C#, correct?

This is correct, somewhat. The reason C# prevents this is that the constructor will not be used, even if its defined in IL, in many cases. Your case is one of these - if you create an array of structs, the constructors will not be called, even if they're defined in the IL.

Unfortunately, there isn't really a workaround since the CLR won't call the constructors, even if they exist.

like image 38
Reed Copsey Avatar answered Feb 13 '26 03:02

Reed Copsey