C
C#2y ago
MrScautHD

❔ Static Field get not called!

Hey i try to make a Registry a static field call the Register Method but the static field get never called, if i would remove the static it would works but it should possible to get it anyway.
22 Replies
MrScautHD
MrScautHDOP2y ago
// OBJECTS
public static readonly StreetLightRenderer StreetLightRenderer = Register("street_light", new StreetLightRenderer());

// OVERLAY
public static readonly CrosshairOverlay CrosshairOverlay = Register("crosshair", new CrosshairOverlay());

private static T Register<T>(string name, T renderer) {
RegistryTypes.Renderers.Add(name, (IRenderer) renderer);

return renderer;
}
// OBJECTS
public static readonly StreetLightRenderer StreetLightRenderer = Register("street_light", new StreetLightRenderer());

// OVERLAY
public static readonly CrosshairOverlay CrosshairOverlay = Register("crosshair", new CrosshairOverlay());

private static T Register<T>(string name, T renderer) {
RegistryTypes.Renderers.Add(name, (IRenderer) renderer);

return renderer;
}
i hope anyone know why my static field get not called
canton7
canton72y ago
What do you mean by "field not get called"? Do you mean the Register method is never invoked?
MrScautHD
MrScautHDOP2y ago
yea but just if the field is static
canton7
canton72y ago
A type's static constructor is called at any point between the assembly being loaded, and a member of the type being accessed for the first time (it's a little bit more complex, with beforefieldinit etc) But basically, Register will be called the first time that someone accesses a member on the type, or at any unspecified point before
MrScautHD
MrScautHDOP2y ago
hää but static works normaly like class get created this field get created too or not? so to fix that i need to remove the static thing or call it? is there no other way? like static and get created instand
canton7
canton72y ago
I'm afraid I'm having a hard time working out what you're saying "get created instand"?
MrScautHD
MrScautHDOP2y ago
like if it not static it get created if a class get created
canton7
canton72y ago
Right, and static fields are created the first time that someone accesses a member on the type. E.g. do var x = WhateverType.CrosshairOverlay, and the static constructor will definitely be run
MrScautHD
MrScautHDOP2y ago
mhh ok and is there nothing else like static like you can acces with the class (no new object) but it get created when a class get created (like in java)
canton7
canton72y ago
Like what in java?
MrScautHD
MrScautHDOP2y ago
in java get the field called when the program start what ever i see its not possible with c#
canton7
canton72y ago
The JLS doesn't think so. It seems to have the same behaviour as C#: https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.4.1
A class or interface type T will be initialized immediately before the first occurrence of any one of the following: - T is a class and an instance of T is created. - A static method declared by T is invoked. - A static field declared by T is assigned. - A static field declared by T is used and the field is not a constant variable (§4.12.4). - T is a top level class (§7.6) and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.
cap5lut
cap5lut2y ago
thats wrong, even in java only if the class will be initialized (which might not be at program start) it executes that.
cap5lut
cap5lut2y ago
ModuleInitializerAttribute Class (System.Runtime.CompilerServices)
Used to indicate to the compiler that a method should be called in its containing module's initializer.
MrScautHD
MrScautHDOP2y ago
Yes but thats already better too I mean i could but its not really clesn
canton7
canton72y ago
I mean, this design isn't really clean. It relies on a static constructor having side-effects which are visible outside of that type
cap5lut
cap5lut2y ago
well, yeah, one (small) thing would be adding a constraint to T for private static T Register<T>(string name, T renderer) instead of blindly casting
MrScautHD
MrScautHDOP2y ago
Yea Well
arion
arion2y ago
System.Runtime.CompilerServicesRuntimeHelpers.RunClassConstructor(typeof(YourClass).TypeHandle); is also an option, you can couple that with reflection of the assembly.GetTypes() if you'd want (It runs the static constructor as well as initializing all static readonly fields I don't advise this reflection approach for SingleFile builds though if you know that this wont mess up your code, you can do
foreach (Type t in Assembly.GetExecutingAssembly().GetTypes())
RuntimeHelpers.RunClassConstructor(t.TypeHandle);
foreach (Type t in Assembly.GetExecutingAssembly().GetTypes())
RuntimeHelpers.RunClassConstructor(t.TypeHandle);
MrScautHD
MrScautHDOP2y ago
nahh i just stay then by the not static one ? ohh i understand
private static T Register<T>(string name, T renderer) where T : IRenderer {
RegistryTypes.Renderers.Add(name, renderer);

return renderer;
}
private static T Register<T>(string name, T renderer) where T : IRenderer {
RegistryTypes.Renderers.Add(name, renderer);

return renderer;
}
you mean that
cap5lut
cap5lut2y ago
yep
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server