CyberBotX
CyberBotX
CC#
Created by CyberBotX on 9/23/2024 in #help
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:
class Test
{
static readonly string Value = throw new NotImplementedException();
}
class Test
{
static readonly string Value = throw new NotImplementedException();
}
Obviously, trying to use that class will result in a TypeInitializationException being thrown. I had thought to use Reflection to do something like this:
typeof(Test).GetField("Value", BindingFlags.NonPublic | BindingFlags.Static)!.SetValue(null, "TestValue");
typeof(Test).GetField("Value", BindingFlags.NonPublic | BindingFlags.Static)!.SetValue(null, "TestValue");
(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?
31 replies
CC#
Created by CyberBotX on 8/3/2024 in #help
When piping into stdin of a non-C# program, need to detect when the program has ended
So I'm trying to make a small C# console application that creates an infinite loop to endlessly output raw binary data to stdout, in order for the data to be read by the stdin of a non-C# program, in this case, RNG_test of PractRand, a C++ program. I was able to make the program enter an infinite loop and send the data, by calling Console.OpenStandardOutput() to get a Stream to write to. But the problem I'm having is that when I pipe the C# program's output to RNG_test, when RNG_test's process ends, the C# program, being in an infinite loop, continues to run until I kill it off with a Ctrl+C. I've been unable to find out if there is a way to determine if the C# program's stdout is still valid to write to or not. Is this possible? As an aside, while searching for this I had come across the CliWrap project, which I thought could let me get around this by feeding a Stream into the wrapped process call and outputting the stdout/stderr of the wrapped process call as if I had called it directly, but I have not found a way to successfully do that. I've attempted to make an "echo" stream, which just stores a MemoryStream that fills when Write is called and send out the data when Read is called, but all this does is cause RNG_test to start and then apparently immediately stop, so I suspect I might not be sending the right data, but I'm not sure why. I don't really know of a good way to just make something like a pass-through Stream.
19 replies
CC#
Created by CyberBotX on 10/18/2023 in #help
❔ How to call static virtual interface method without completely reimplementing in derived class
This mainly pertains to generic math in C# 11 / .NET 7, but say I have a minimum of something like this:
interface ITest
{
static virtual void Test() => Console.WriteLine("Test");
}
class Testing : ITest
{
}
interface ITest
{
static virtual void Test() => Console.WriteLine("Test");
}
class Testing : ITest
{
}
I cannot find a way to call the Test method from ITest without just redefining it entirely in Testing, even if said redefining is 100% identical to the interface's code (which seems terrible to me). Obviously I can't call ITest.Test() because it is an interface and not a class, and I can't call Testing.Test() because the method technically doesn't exist on Testing. The only workaround I've found is doing something like void RunTest<T>() where T : ITest => T.Test(); and calling it via RunTest<Testing>(); but that doesn't work for my purposes. I also can't define the method in Testing as public static void Test() => ITest.Test(); for the same reason as being unable to just call the last part due to it being on an interface.
9 replies