Is it possible to use Reflection to replace a static readonly field without the static constructor?
So, say for example I have a class like the following:
Obviously, trying to use that class will result in a
TypeInitializationException
being thrown. I had thought to use Reflection to do something like this:
(The exception is thrown when SetValue is called, not when GetField is called.)
But this results in the type being initialized and thus the same exception is thrown. I know that trying to do something like this is probably frowned upon, but I am trying to get around an issue in an externally generated class that I'd rather not modify (despite that I could in this case) just in case I have to re-generate the file again. So is there any way around this to be able to replace the value of that static readonly field without the static constructor being called and thus throw an exception?20 Replies
despite that I could in this caseThen do. Anything else will just be a dirty half-working volatile workaround Assuming you can find a workaround at all
OK, so I could, yes, but then I would lose the changes I make if I regenerate the class from the external tool that generated it in the first place. So I'd rather not have to remember to replace that code every single time I regenerate the class, I'm more likely to forget to do so than remember to do so.
Ah, well, that's some garbage tool you're using, then
I feel like the better approach would be to look into ways to stop the tool generating such code in the first place
:This_rrc:
I have absolutely no control over that part of its output. The tool in question is the Hime parsing generator in this case. I can't tell it not to do what it is doing, the only way I probably could would probably be to fork the tool and edit the tool, and that sounds very undesirable (especially since the tool is written in Rust and I don't know Rust).
I'd raise them an issue for sure
To answer your question, though, nothing can be done, not even with reflections
throw
ing in an assignment to a field is a syntax error
Does this code even compile in the first place?The file does compile, yes. The error is a runtime error, not a compile error. The actual generated code is looking for a file in the project's resources, while I'd rather change it so it just accesses a file directly. Plus, the error from my use of Reflection happens when I call SetValue and it is because the static constructor gets called before it can set the value, which I understand is how things would normally work. But if nothing can be done, then that's fine, I'll just have to edit the class and hope I remember to do so every time, even if that is error-prone.
I guess you could try source generators
There is a way to rewrite a bit of code, when you know the exact position that should be rewritten
You could do, basically, the equivalent to
https://andrewlock.net/exploring-the-dotnet-8-preview-changing-method-calls-with-interceptors/
So, as I mentioned at the start, the call to GetField isn't a problem, because that doesn't cause the constructor to run. It is when SetValue is called that is the problem, because it does cause the constructor to run. Although I've since decided to make this a non-issue as I have decided not to bother using the code now.
But... It's not a technical solution
It doesn't work. And if you read the question, you'd understand why
Unknown User•2mo ago
Message Not Public
Sign In & Join Server To View
anyway, you can’t do it even if there was no static constructor
reflection does not allow you to set static readonly fields
cannot be done
you can throw from a field like that?
Maybe you can inherit that class and hide the field?
It wont change the actual value of the original tho
You cannot, that's the issue
but didnt he reply yes to this? o wells, im lost and doesnt look like this is going to be resolved
The code I put up above was an example, not literally what was being done. The actual code was calling a method which would eventually throw an exception.
If you have no further questions, please use /close to mark the forum thread as answered