0
votes

Structs defined in C# can't have parameterless constructors. However, as I understand, such constructors are allowed by CLR. There are .NET libraries that contain them (see structs like Vector3 in UnityEngine.CoreModule which is .NET 3.5).

The question is, is there an easy way to add parameterless constructors to some structs in my .NET assembly (not in its source code)? Should I somehow mess with the assembly's IL after building it? How possibly Unity could have achieved this with their assembly?

UPDATE: actually all structs have an implicit parameterless constructor created by compiler, even if there is a parameterful constructor defined (see AndyJ's comments below). There is nothing magical in Unity3D's structs. Still I'm curious about a way to add a custom parameterless constructor to a class.

I know the behaviour of such constructors can cause confusion (see linked question), but I'm anyway curious how to have one. If someone is interested why: this all started with my DI container (Zenject) that is in some cases trying to create instances of my structs using parameterful constructors. It fails because it doesn't know how to resolve primitive types (like Int32) in my struct's constructor. I can easily avoid this by creating a binding from Int32 to 0 — however, before realising this, my curiosity has already awaken.

1
Given that C# doesn't allow it, is there some way to do it on the assembly level? The answer is obviously yes if you write or generate raw IL, and there may be some post-compile IL rewriters out there that can do it (though I have no experience with them). Trickier would be the cases where the constructor isn't even invoked, even when it's present -- whether a DI container will do so would depend on how it's written.Jeroen Mostert
Do you have a link showing that Vector3 has a parameterless constructor? I can't see it in the documentation of various forms of source code I looked at. Obviously it has the "normal" one which constructors it to 0, but you say it has a custom one?user310988
@AndyJ Unity3D's documentation is famous from being unprecise and incomplete. It indeed doesn't mention Vector3(), but Assembly Explorer does see it and it's possible to call this constructor explicitly. And yes, it is a struct, not a class. If you want to check, I'm pretty sure you can easily find UnityEngine.CoreModule.dll in the web.Павле
All structs have an implicit empty constructor. It's not that "Structs defined in C# can't have parameterless constructors.", but rather "It is an error to define a default (parameterless) constructor for a struct." docs.microsoft.com/en-us/dotnet/csharp/programming-guide/… "If you instantiate a struct object using the default, parameterless constructor, all members are assigned according to their default values." Every struct you make has a parameterless constructor, it's just you can't control whats done in it. dotnetfiddle.net/b3jjOmuser310988
I grabbed UnityEngine.Core.dll from my local machine, popped it in dotPeek and confirmed that it doesn't have a custom parameterless constructor. You can call it using a parameterless constructor, because that's the default parameterless constructor provided by .net for every struct. Unless I'm missing something and you can provide a link showing otherwise?user310988

1 Answers

0
votes

You can always cheat the system by implementing a "MakeEmptyStruct" method, which creates and returns (or assigns) one of your structs with default values