CyberBotX
Is it possible to use Reflection to replace a static readonly field without the static constructor?
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.
31 replies
Is it possible to use Reflection to replace a static readonly field without the static constructor?
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.
31 replies
Is it possible to use Reflection to replace a static readonly field without the static constructor?
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.
31 replies
Is it possible to use Reflection to replace a static readonly field without the static constructor?
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).
31 replies
Is it possible to use Reflection to replace a static readonly field without the static constructor?
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.
31 replies
When piping into stdin of a non-C# program, need to detect when the program has ended
So, what I've tried:
1. Making a
Process
and redirecting its StandardInput
. This technically works, but the downside is I get no output and if I try to redirect its StardardOutput
, I end up in a state where it won't proceed because, as far as I can tell, because of how Process handles reading and writing from both input and output.
2. Going back to CliWrap
, I found a set of stream from the Nerdbank.Streams
package, so I used their SimplexStream
. Results vary... The Task that is part of CliWrap's Command
seems to be constantly in a state of WaitingForActivation
even it somehow the process ends. And I'm not sure what combination of things I'm doing results in the C++ program even reacting to stuff on its stdin.
3. Also using CliWrap
, I had to make a version of that SimplexStream
that auto-flushes on each write, I got that idea from a GitHub issue on CliWrap. I also had to write my code so it would create the Task
of the CliWrap command, created a Thread
that runs the infinite loop, start the thread and immediately afterwards await the command. This works. If I use that as the pipe to stdin for the C++ program and then pipe its stdout to calling Console.Write, it works, but... output doesn't seem buffered very well. I was able to actually make PractRand's RNG_test work properly by adding a call of setvbuf(stdout, nullptr, _IONBF, 0);
at the start of the program. I had to do the same for a TestU01 program. So maybe there is nothing that can be done on the C# side to get around the C++ program not buffering its output. But as far as outputting the C++ program's stdout to the C# program's stdout, what doesn't work is trying to copy to the stream I get from Console.OpenStandardOutput()
. I instead have to pipe things to Console.WriteLine (or Console.Error.WriteLine for stderr).19 replies
When piping into stdin of a non-C# program, need to detect when the program has ended
I do think one of the only problems with that, at least with the fact that StandardInput is a StreamWriter instead of a Stream, is it makes it harder to do what I'm currently doing, since it treats the input stream as a character stream instead of a binary stream.
19 replies
When piping into stdin of a non-C# program, need to detect when the program has ended
I could try just using a basic Process class, but in the morning, I gotta get some sleep. It's a bit of a hard thing to search Google for, either I get answers related to PipeStream (which is for named pipes and also not valid for my situation) or talking about the opposite situation (data being piped into the C# program instead of out) or talking about looking at Process's StandardOutput instead.
19 replies
When piping into stdin of a non-C# program, need to detect when the program has ended
I tried to do that with CliWrap, but in order to write to the C++ program's stdin, I need to use a Stream and I don't think C# has any built-in Stream-derived types that can just take data being written to it and spit it back out when read from.
19 replies
When piping into stdin of a non-C# program, need to detect when the program has ended
So, firstly, I'm not using
Console.ReadLine
, I'm using Stream's Write
with a Span<byte>
that is either 4 bytes or 8 bytes long (depending on if I am writing a 32-bit integer or a 64 bit-integer). Besides which, I'm writing to stdout, not reading from stdin. Also, no, this isn't a microservice. I only have control over the C# program, unless I actually modify the code of the accepting program (which I don't want to do, since I could use this piping C# program in more than just the one program). As such, I don't have event requests coming in. The accepting program is just reading from its stdin, which is coming from my C# program's stdout. So while I get what those suggestions are suggesting, neither one is valid for my purposes.
What I'm doing is basically trying to test C# versions of PRNGs, to do so, I am wanting to pipe the output of the PRNG directly into testing utilities, in this case, I'm piping into the stdin of PractRand's RNG_test, dieharder, and TestU01 via a program that reads from stdin. I could, in theory, modify the code of RNG_test but I would much prefer not to since it is not my code to begin with. I can't modify the code of dieharder. The TestU01 wrapper I could modify, but it is in C++, not C#, and as mentioned before, its only purpose is to read from stdin and run TestU01 on the incoming data.19 replies
❔ How to call static virtual interface method without completely reimplementing in derived class
(I just really don't want to copy/paste the code from the interfaces into my code unless I absolutely have to, even though I can see that .NET itself has done that for some things, like for instance, int's CreateChecked is just a carbon copy of the INumber<T> code.)
9 replies
❔ How to call static virtual interface method without completely reimplementing in derived class
I guess related to this, then, I'm trying to do this for one of the static virtual properties in IBinaryNumber and it isn't letting me do it. If I have a class that is like:
With
Helpers
being a static class containing:
The two errors say that it cannot be used as a type argument (trying to say there is no specific implementation for IsPow2, despite that the class for TSelf
does have IsPow2 on it) and that it cannot be used as a type parameter for TSelf
because it can't convert IBinaryNumber<Testing>
into IBinaryNumber<IBinaryNumber<Testing>>
. If I change the type parameter to just Testing
, it compiles but gives me an obvious stack overflow.9 replies
❔ How to call static virtual interface method without completely reimplementing in derived class
I see. I was just mentioning on another server that I could also do this:
Then I can call
Testing.Test();
and it works, but it looks ugly to me. But it might be what I need to do because I want it so I call the method for the class, not from a method external of the class.9 replies