C
C#•3mo ago
Synae

Issue with dynamic

Hey there. I'm having an issue and I can't figure out how to fix it. There's this enum somewhere in another assembly, whose type is obfuscated and changes regularly:
enum SomeRandomCharacters {
SPRING,
SUMMER,
AUTUMN,
WINTER
}
enum SomeRandomCharacters {
SPRING,
SUMMER,
AUTUMN,
WINTER
}
I'm trying to use it with Reflection. I retrieve the type by checking the first argument to a method in that same assembly that I know uses it.
// Here's what I had and it's working so far:
Type enumType = Type.GetType("SomeType").GetMethod("ThatOtherMethod").GetParameters()[0].ParameterType;

if (Enum.TryParse(enumType, "SPRING", out var myEnum)) {

// The following correctly prints that enum member and type
Log($"{myEnum} ({myEnum.GetType()})");

// But what I really want to do is this:
SomeType.ThatOtherMethod(myEnum);
}
// Here's what I had and it's working so far:
Type enumType = Type.GetType("SomeType").GetMethod("ThatOtherMethod").GetParameters()[0].ParameterType;

if (Enum.TryParse(enumType, "SPRING", out var myEnum)) {

// The following correctly prints that enum member and type
Log($"{myEnum} ({myEnum.GetType()})");

// But what I really want to do is this:
SomeType.ThatOtherMethod(myEnum);
}
That last line doesn't work because it complains that it cannot convert from object to Season. I cannot use the enum's type myself to cast it so I thought making myEnum dynamic would work:
if (Enum.TryParse(enumType, "SPRING", out dynamic myEnum)) {
if (Enum.TryParse(enumType, "SPRING", out dynamic myEnum)) {
But it doesn't. An exception gets thrown at runtime that simply says:
System.TypeLoadException: Failure has occurred while loading a type.
I tried many other variations, thinking that maybe I could help it understand what type it is better, to no avail. Is there anything I can do achieve what I want or fix that dynamic issue I'm having?
21 Replies
TheBoxyBear
TheBoxyBear•3mo ago
So you have access to ThatOtherMethod in your assembly which is aware of the parameter type. What is the problem with casting to it?
Synae
Synae•3mo ago
My issue is that the type of the enum changes with every update and I'm just trying to make it so that I don't have to update my mod every week just because of that. So I'm trying to find a way to retrieve and use it programmatically. Also, that method is in the other assembly as well.
TheBoxyBear
TheBoxyBear•3mo ago
In that case you could always invoke the method through reflection But that method is also provided by another assembly so you don't have control over its signature?
Synae
Synae•3mo ago
I don't, but I can get it with reflection, I'm already doing it. I just absolutely didn't think of using Invoke to call it.
TheBoxyBear
TheBoxyBear•3mo ago
Well there you go then 🙂
Synae
Synae•3mo ago
There are actually a few methods I'm calling with that enum as a parameter (which I'm currently retrieving each week, and updating the mod with the new name). I'd rather not have to use reflection for all of them. Thank you anyway for that idea though, I really didn't think about it for some reason.
TheBoxyBear
TheBoxyBear•3mo ago
Unless you were to dive into code generation, there's not really other ways
Cattywampus
Cattywampus•3mo ago
is this for modding?
TheBoxyBear
TheBoxyBear•3mo ago
It seems but with a public api
Synae
Synae•3mo ago
Yes What do you mean by that?
TheBoxyBear
TheBoxyBear•3mo ago
Source Generators - C#
Source Generators is a C# compiler feature that lets C# developers inspect user code as it is being compiled. Source generators create new C# source files on the fly that are added to the user's compilation.
TheBoxyBear
TheBoxyBear•3mo ago
You'd still need to update though but the process could be automated and integrated into a pipeline
Synae
Synae•3mo ago
Thanks. But shouldn't dynamic work for my case? Is there a reason it doesn't?
WEIRD FLEX
WEIRD FLEX•3mo ago
this seems weird to me that it doesn't work, are you sure you are using the correct type? i would try casting the enum just in case (say for example expression.cast) also dynamic wouldn't really change anything, is the type is right then you can just pass the parameter as an object you could cast the method to an Action/Func and have explicit types, tho
Synae
Synae•3mo ago
I am using the correct type. Using my example in the opening post, the ide complains:
No description
Synae
Synae•3mo ago
If I simply manually cast it, everything works (not just in the ide, I tested it properly):
No description
Synae
Synae•3mo ago
And I don't understand your last sentence.
WEIRD FLEX
WEIRD FLEX•3mo ago
wait, i have a doubt you said the method you are calling is in the obfuscated assembly, right? if it's publicly exposed then how is it possible that the enum type name is crap like ΩὠΩὠΩὠΩὠ
If I simply manually cast it,
in fact my idea was to try to replicate this but if you are reading the type from this assembly which is updated every now and then, really i don't see many other ways than to do it by hand either the type is recognizable in some way, then you could think of automating this, or it's hard work
Synae
Synae•3mo ago
Not all of their assembly is obfuscated. I'd say it's 75/25. So I try to work as much as I can with the 25. I'm just surprised that dynamic doesn't work. I thought the whole point of it was that it's supposed to infer type at runtime, but it's failing for something I thought would be trivial. Bumping this up as I'd like to understand why dynamic isn't working, and in case someone else has an idea on how to do what I want.
WEIRD FLEX
WEIRD FLEX•3mo ago
did you try debugging the call line SomeType.ThatOtherMethod(myEnum); enabling stepping in the .net framework? if i had to guess i'd point to the UpdateDelegates class also tbh have you tried reproducing the issue with a sample? because i wouldn't want that the obfuscation has to do something about this
Synae
Synae•3mo ago
It throws the exception way before that. I tried debugging lines before the one that uses dynamic and those debugs don't even get executed, as if it's throwing as soon as it enters the method that's gonna do all that. According to https://learn.microsoft.com/en-us/dotnet/api/system.typeloadexception
The exact timing of when statically referenced types are loaded is unspecified. This exception may be thrown before the method that references the missing type starts executing.
Also no, I have not tried replicating it, will do.