c# - How to detect an attribute property using a source generator? - Stack Overflow

admin2025-04-29  2

I'm trying to learn and use source generator in C#, but I'm having few issues.

I want to make use of some C# new features, like generic attribute, and use it to generate custom code.

I have for example these attribute:

namespace StrongValues;

[AttributeUsage(AttributeTargets.Struct, Inherited = true, AllowMultiple = false)]
public class StrongValueAttribute<TValue> : StrongValueBaseAttribute
    where TValue : IEquatable<TValue>, IComparable<TValue>
    ;

[AttributeUsage(AttributeTargets.Struct, Inherited = true, AllowMultiple = false)]
public abstract class StrongValueBaseAttribute : Attribute
{
    public ConvertOperator ValueToStrongOperator { get; set; } = ConvertOperator.Implicit;
    public ConvertOperator StrongToValueOperator { get; set; } = ConvertOperator.Explicit;

    public bool UseJsonConverter { get; set; } = true;
    public bool UseTypeConverter { get; set; } = true;
}

public enum ConvertOperator
{
    _ = 0,
    None = _,
    Implicit,
    Explicit
}

What I want when I use the attribute, like here:

namespace NS

[StrongValue<string>]
public partial struct Email;

is to generate the following:

// Generated

namespace NS;

partial struct Email
{
  public string Value { get; init; }
}

I'm trying to make a stripped version from StronglyTypedId, but I don't know how to detect the attribute properly.

I'm trying first to detect struct types:

        var structsToGenerate = context.SyntaxProvider
                .ForAttributeWithMetadataName(
                    Parser.StrongValueAttributeDisplayName,
                    predicate: (node, _) => node is StructDeclarationSyntax,
                    transform: Parser.GetStructSemanticTarget)
                .Where(static m => m is not null)
                ;
    
// Not sure what should be the name here since it's generic.
public const string StrongValueAttributeDisplayName = "StrongValues.StrongValueAttribute`1";

Is this the right way to detect the attribute? How can I get the generic type?

string tValue = null!;

        foreach (AttributeData attribute in structSymbol.GetAttributes())
        {
            if (!(
                (attribute.AttributeClass?.Name == "StrongValueAttribute"
                || attribute.AttributeClass?.Name == "StrongValueAttribute`1"
                || attribute.AttributeClass?.Name == "StrongValue"
                || attribute.AttributeClass?.Name == "StrongValue`1")
                && attribute.AttributeClass.ToDisplayString() == StrongValueAttributeDisplayName))
            {
                // wrong attribute
                continue;
            }

            (var hasMisconfiguredInput, attrProps) = GetConstructorValues(attribute);

            if (hasMisconfiguredInput) return null;

            tValue = attribute.AttributeClass!.TypeArguments.First().ToDisplayString();

            if (tValue is null) return null;
        }
转载请注明原文地址:http://anycun.com/QandA/1745937856a91376.html