C# Analyzers (& Source Generators)

Been browsing around C# to see what I can help with - I see #1448 as fairly straightforward, but I’m struggling to come up with something that explains why this is a useful concept in the first place.
Given reflection is discouraged in general, I feel like this would make sense to have an analyzer track in general. It’s an advanced & niche concept, but so are analyzers.

Thoughts? I’d be happy to make a track for this, given I have lots of experience, but wanted to see whether this makes sense in the first track.

(Also, I wasn’t sure if I should just open an issue, but I figured this would be less intrusive since I haven’t quite figured out how this community operates :sweat_smile:)

Hello - thanks for wanting to help :slight_smile:

Tracks are for languages. So there wouldn’t be an analyzer track or any similar thing.

Given reflection is discouraged in general

Do you have a source for this? Metaprogramming is a very useful and powerful thing in lots of languages (I use it daily in Ruby for example) - is there a reason it’s not in C#?

Also, I wasn’t sure if I should just open an issue

Forum post is best! :slight_smile:

(cc @ErikSchierboom)

Ah, sorry I haven’t quite figured out what is called what here (I guess a series of exercises that unlock each other is what I mean?)

Metaprogramming in my mind is working with the compiler to make more code (and sometimes analyze). Which is exactly what analyzers & source generators do.

The discussion about what is best is obviously more nuanced, but reflection is a bad solution to most problems it is (or has been?) applied to - it is incompatible with AOT & many optimizations, and AOT is becoming more and more dominant when it comes to production deployments.

Looking at the source gen docs there are a lot of techniques, with the dominant ones being reflection (as it’s easy and quick to setup) and source generators being the new performance-oriented .NET Core option.

There’s Fody (which is the dominant IL weaving lib iirc), but that’s so specialized I doubt it’s worth a consideration.

So in my mind, a simple analyzer is the best way to demonstrate what attributes are good for.

I’d think of it to work this way:

  • Attributes (how to define them, how & where to apply them)
    • Includes some kind of example usage that already does something. There’s plenty to choose from, ie “Obsolete”?)
  • Custom Analyzer
    • A super simple setup that analyzes a project & reacts to some pattern/attribute.
    • Not sure how possible given this requires two separate .csprojects to reference each other.
  • Source Generator
    • Super simple (incremental? could factor this out into it’s own thing) source generator that generates a type/function based on some pattern/attribute.

I want to point out again that I’ve just discovered this awesome project & am not aware of how this usually works. Maybe these exercises are too big / too small. Please do point anything out!

1 Like

Thanks for replying! I’ll leave @ErikSchierboom to discuss this as he maintains the C# track. A series of exercise could make sense though. Erik has probably considered all this previously and has ideas though, so I’ll let him inform us! :slight_smile:

You mean attributes and why they’re useful? Well, they’re incredibly useful as metadata. Whether that metadata is used at runtime (reflection) or compile-time (source generators), is sort of the next step. Maybe a good way to explain their use is to show use cases where they are being used, e.g. ObsoleteAttribute being read by the compiler/IDE or JsonPropertyName to specify a property/field’s JSON name.

I feel like reflection is more about reasoning about your code at runtime. The very fact that you can get an object’s type and depending on that type do specific things can be incredibly useful. In many use cases, it does not have to involve code generation at all. Reflection can also be really useful for generic collections.

We have one exercise already that deals with using attributes (not defining them): https://github.com/exercism/csharp/blob/main/exercises/concept/attack-of-the-trolls A great new exercise would have one define custom attributes (and using them).

Are you referring to a Roslyn Analyzer? If so, I think that would be (way) too complicated, as it requires a lot of knowledge about syntax trees and more.

Yes this would a great new exercise.

Thanks for the detailed response.

I agree that ObsoleteAttribute or similar might make a good example, the issue i’m really raising is that the “(and using them)” part either falls away, is only relevant to a specific attribute (ie explaining Obsolete is not so helpful imo) or requires knowledge of another language / runtime feature (reflection, analyzers…)
Not super clear which one of these you’d prefer, but I’d prefer introducing a different concept first (as using attributes ie for Json parsing really doesn’t require much explanation) and then explaining custom attributes once we have a good grasp where it could be used.

Also on analyzers / source generator exercises - Source Generators are just analyzers that can produce code, so I don’t see how an analyzer will be too complicated but a source generator would make sense.

I don’t mind that it’s specific to one attribute, we just teach students how to use attributes. The goal is not to teach them about all attributes, just what attributes are and how to use them.

Is that true? They’re both working with syntax, but they have different purposes and structure.