Uh oh!
There was an error while loading. Please reload this page.
When invoking class constructor ensure class is initialized - #40293
Conversation
Dotnet-GitSync-Bot
commented
Aug 3, 2020
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
| [Fact] | ||
| public void Invoke_StaticConstructorMultipleTimes() | ||
| { | ||
| ConstructorInfo[] constructors = GetConstructors(typeof(ClassWithStaticConstructorThatIsCalledMultipleTimesViaReflection)); |
There was a problem hiding this comment.
BTW this test library doesn't run against .NET Framework, so you'd have to paste this into a test program if you wanted to be sure NETFX behavior was the same.
jkotas
commented
Aug 3, 2020
Does this create easy path to mutate read-only statics (by accident)? We have disallowed setting of read-only fields via reflection in .NET Core. This is a more subtle variant of the same. I think it may be better to fix this by disallowing static cctor invocation via reflection. |
jkotas
commented
Aug 3, 2020
Or to allow it just once. |
davidwrighton
commented
Aug 3, 2020
This creates all sorts of questionable paths. But they aren't new. @danmosemsft I've verified that this is the behavior of Netfx 4.8. I'd be pleased to convert an attempt invoke the static ctor via this mechanism into a simple call to RunClassConstructor instead of actually, you know, repeatedly invoking the class constructor directly. The current checked in scheme is clearly not safe, as it doesn't behave reliably, and can skip critical aspects of cctor invocation. |
jkotas
commented
Aug 3, 2020
+1 |
| { | ||
| // Run the class constructor through the class constructor mechanism instead of the Invoke path. | ||
| // This avoids allowing mutation of readonly static fields, and initializes the type correctly. | ||
| RuntimeHelpers.RunClassConstructor(DeclaringType!.TypeHandle); |
There was a problem hiding this comment.
Can we get here for module constructors? I believe DeclaringType is going to be null for them.
There was a problem hiding this comment.
Sigh, we can. I'll update the code to handle them by running the module constructor api.
…0293) When invoking the class constructor method via reflection invoke, ensure that the class constructor is run via the standard run class constructor pathway instead of running it explicitly. Do the same for module constructors.
When invoking the class constructor method via reflection invoke, ensure that the class constructor is run via the standard run class constructor pathway before manually invoking the class constructor
This ensure that all of the various data structures associated with the class constructor are initialized such as valuetype statics.
Fixes#1748