C
C#6mo ago
orlac

Pattern matching `Type` in a way that can be assigned to a `const` variable... is it possible?

I'd like to come up with something where i can just have a lookup for a bunch of GUIDs that are assigned for each type. I write this, but it won't compile (I end up with error: CS8121 - but MS docs don't have any specifics about it for some reason). I had it implemented by taking in an object, which worked ok (it compiled at least), but I need to be able to do this lookup and assignment before any objects exist since it needs to be assigned to a const member variable. Any help/workarounds would be appreciated... it doesn't need to be structured exactly like this for the input or patterns in the switch, i'm just not too sure what other options I have when it comes to assigning the result to a const variable:
internal static class Constants {
public static string GUID(Type type) {
return type switch {
TypeA => "DEADBEEF-FEEE-FEEE-CDCD-000000000000",
TypeB => "DEADBEEF-FEEE-FEEE-CDCD-000000000001",
TypeC => "DEADBEEF-FEEE-FEEE-CDCD-000000000002",
TypeEtc => "DEADBEEF-FEEE-FEEE-CDCD-000000000004",

null => throw new ArgumentNullException(
$"GUID lookup failed, {nameof(type)} is null"
),
_ => throw new ArgumentException(
$"GUID lookup failed, type {type.Name} missing from GUID map"
),
};
}
}
internal static class Constants {
public static string GUID(Type type) {
return type switch {
TypeA => "DEADBEEF-FEEE-FEEE-CDCD-000000000000",
TypeB => "DEADBEEF-FEEE-FEEE-CDCD-000000000001",
TypeC => "DEADBEEF-FEEE-FEEE-CDCD-000000000002",
TypeEtc => "DEADBEEF-FEEE-FEEE-CDCD-000000000004",

null => throw new ArgumentNullException(
$"GUID lookup failed, {nameof(type)} is null"
),
_ => throw new ArgumentException(
$"GUID lookup failed, type {type.Name} missing from GUID map"
),
};
}
}
The assignment was planned to be something like this:
private const string GUID = Constants.GUID(TypeA);
private const string GUID = Constants.GUID(TypeA);
It's probably also worth mentioning this is for a VS2022 extension just to keep all of the extension component GUIDs defined in one place, so if there are alternatives to doing something like this (like some Visual Studio specific resource/config specific utilities I haven't found yet or something like that) i'd be happy to hear any suggestions anyone might have for this type of thing.
30 Replies
333fred
333fred6mo ago
Unfortunately, it isn't possible to do this
orlac
orlacOP6mo ago
damn... do you happen to know of any potential workarounds? or do i need to just define the GUIDs as const strings in that Constants class (or something along those lines)?
333fred
333fred6mo ago
Nope. I think you need to just define them as constants
orlac
orlacOP6mo ago
ah, oh well. glad I can at least stop wasting time trying to get this snippet working at least haha. one more question for you if you don't mind... do you happen to know why wrapping the input and the pattern strings in nameof() doesn't end up working either? are nameof() and typeof() both evaluated at runtime or something like that?
333fred
333fred6mo ago
Not sure what you mean; can you show an example?
orlac
orlacOP6mo ago
No description
333fred
333fred6mo ago
What do you think that's doing 😄
orlac
orlacOP6mo ago
guessing nameof(type) isn't getting the actual typename then lol
333fred
333fred6mo ago
Look at what you're doing in the null branch That'll give you a good hint
orlac
orlacOP6mo ago
does that just return the variable name or something like that?
333fred
333fred6mo ago
Correct
orlac
orlacOP6mo ago
yep haha, damn
MODiX
MODiX6mo ago
333fred
REPL Result: Success
Type type = typeof(string);
nameof(type)
Type type = typeof(string);
nameof(type)
Result: string
type
type
Compile: 209.222ms | Execution: 23.230ms | React with ❌ to remove this embed.
orlac
orlacOP6mo ago
and i'm guessing i can't approach it with a similar concept (except with an approach that works :pepe_laugh:)?
333fred
333fred6mo ago
Not if you need constness You can't use System.Type in most const areas, except attribute arguments
orlac
orlacOP6mo ago
i'm a c++ programmer so i'm very out of my element with this stuff lol. i'm guessing anything in the Reflection library also won't be compile time, assuming that's actually what const boils down to in C#... do i have that part right at least? and yeah i'm pretty sure const is necessary since these get passed into attributes that then do some dark magic involving dependency injection
333fred
333fred6mo ago
There is no real equivalent to constexpr in C# But yes, the whole point of reflection is that it isn't compile time
orlac
orlacOP6mo ago
yep, makes sense
Angius
Angius6mo ago
If you really need something like that but on compile time, source generators are your best bet
orlac
orlacOP6mo ago
ok thanks for all of the info... you cleared up a handful of things for me. time to start hardcoding GUIDS haha
333fred
333fred6mo ago
This is so not worth a source generator
Angius
Angius6mo ago
Oh for sure But it's an option
orlac
orlacOP6mo ago
yeah if it's something where people with actual C# experience would consider a pain, it definitely isn't needed for this project then haha. i'm dealing with enough pain trying to work with the collection of Visual Studio SDKs.... they seem to be in a state where they're in the middle of migrating from a few older SDKs into a newer model. Somehow I think i ended up where i need to use both the old and new SDK for what i'm trying to build. although, now that I think about it, i think some of the resource files worked into the VS SDKs will handle source generation for strings (mostly for localization)... but i'll have to see if these end up working out OK using one of those resource files. you're talking about code gen like this file, right?... or did you mean something else entirely? https://github.com/vorlac/cppreference-docs-vs-extension/blob/main/CppReferenceDocsExtension/Resources/VSPackage.Designer.cs ^ that gets generated from this file: https://github.com/vorlac/cppreference-docs-vs-extension/blob/main/CppReferenceDocsExtension/Resources/VSPackage.resx
Angius
Angius6mo ago
I rarely work with resx files, so not sure if they use source generators Entirely possible they do
orlac
orlacOP6mo ago
the top link is what the resx ends up as after it runs through some special compilation process that VS provides
Angius
Angius6mo ago
https://devblogs.microsoft.com/dotnet/introducing-c-source-generators Might be it's some tool built into VS, dunno Source generators are generally IDE-agnostic Used either as a reference to them, or just distributed via nuget like any other package
orlac
orlacOP6mo ago
the one used in this project is whatever this is: https://github.com/vorlac/cppreference-docs-vs-extension/blob/main/CppReferenceDocsExtension/CppReferenceDocsExtension.csproj#L139-L142
<EmbeddedResource Include="Resources\VSPackage.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>VSPackage.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Resources\VSPackage.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>VSPackage.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
^ that part... the ResXFileCodeGenerator if that doesn't end up working i may actually mess around with the stuff that article goes over. it doesn't seem to bad. C# as a language is quite nice to mess with whenever i'm not trying to fight my way through the SDKs i need to use and actually get to implement stuff. I think it's the first language I've tried in the past decade that actually has a decent approach to parsing XML
Angius
Angius6mo ago
C# is definitely nice, but source generators... they're better than they were, with incremental source generators and some convenience methods, sure But interacting with Roslyn APIs to inspect the project is a whole undocumented mess of spaghetti and nonsense Generating simple stuff is easy-ish, though
orlac
orlacOP6mo ago
yeah, i know what you mean. this type of thing has been my entire experience with these SDKs so far haha. I ended up needing one library to run the out of process parts of the extension, then had to link (or whatever it'd be called in C# - "referenced" maybe haha) that to another library that runs the other parts of the extension in the same process as VS2022... plus need to wrangle the C++ LSP to get selected symbol information, needed to get a WebView2 working in this weird mixed environment of SDKs, etc etc. The stuff I thought would take the least amount of time have taken over the past few weekends for me haha. At least when this is done a somewhat comprehensive example will be out there for people to use as a reference. MS has tons of examples, somehow none of which truly show me how to approach some of this stuff. Just bits and pieces from their examples have slowly guided me towards something that's starting to work when it comes to the VS side of things. Once that's out of the way I should be able to actually sit down and mess around with the language a lot more since I can just implement the inner workings of it all and not have to worry about the scattered docs / examples they have for the SDKs. anyway, thank you both for the help 👍 . I think the info you gave me should get me past trying to get this type pattern matching to work.
Angius
Angius6mo ago
Anytime :Ok:
Want results from more Discord servers?
Add your server