Search code examples
c#oopsourcegenerators

Set a maximum count for parent-child object initialization c#


TL;DR ?:(

hi, I'm creating a source generator, It's been a pain since I started TBH.

I have a class:

public class CsharpTypeBase
{
    public CsharpTypeBase(int childCount = 0)
    {
        childCount++;
        if (childCount < 5)
        {
            Child = new(childCount);
        }
    }
    public bool IsSimple { get; set; }
    public bool IsArray { get; set; }
    public bool IsIEnumerable { get; set; }

    public ref CsharpTypeBase? Child
    {
        get => ref _child;
    }

    public string? ValueIfIsSimple
    {
        get => _valueIfIsSimple;
        set
        {
            IsSimple = true;
            _valueIfIsSimple = value;
        }
    }
    public CsharpClassModel ClassModel
    {
        get => _classModel;
        set
        {
            IsSimple = false;
            _classModel = value;
        }
    }
    private string?          _valueIfIsSimple;
    private CsharpClassModel _classModel = new();
    private CsharpTypeBase?  _child;
}

which is a base class for other CSharp types that I have(ex: ReturnTypes,Parameters,Properties)

with the following code im trying to parse c# classes into simpler versions(and after that do something with them):

public static CsharpTypeBase Convert(TypeSyntax typeSyntax)
{
    var output = new CsharpTypeBase();
    FromTypeSyntax(typeSyntax,ref output);
    return output;
}
private static void FromTypeSyntax(TypeSyntax typeSyntax,ref CsharpTypeBase output)
{
    switch (typeSyntax)
    {
        case PredefinedTypeSyntax predefinedTypeSyntax:
            output.ValueIfIsSimple = predefinedTypeSyntax.Keyword.ValueText;
            output.IsIEnumerable = false;
            output.IsArray = false;
            break;
        case IdentifierNameSyntax identifierNameSyntax:
            CsharpClassModel.RecursivelyWalkThroughTheClass(identifierNameSyntax.Identifier.ValueText,output);
            break;
        case ArrayTypeSyntax arrayTypeSyntax:
            output.IsArray = true;
            output.IsIEnumerable = false;

            FromTypeSyntax(arrayTypeSyntax.ElementType,ref output.Child!);
            break;
        case GenericNameSyntax genericNameSyntax:
            var (innerClass,isEnumerable) = FindTheMostInnerType(genericNameSyntax);
            output.IsIEnumerable = isEnumerable;
            
            FromTypeSyntax(innerClass,ref output.Child!);
            break;
    }
}

as you can see it's a recursive function, and its doing just fine, the only problem I have with this design is (that Child property) it's not really memory friendly and stable because of my base class, by default it's creating 5 child class(which is the same type as my base, it's stupid but I cant thing of anything else).

I want this to be more efficient, what if I only need 2 children? or worse, what if I needed more children to be created? I need the Exact Count otherwise it will OverFlow (by creating infinite objects) or blow up:

FromTypeSyntax(arrayTypeSyntax.ElementType,ref output.Child!);

this code should somehow set a maximum count for :

Child = new();

And the reason I need that Child property is to parse/convert this kind of incoming types:

List<string>[] one,
List<string[]> two,
Task<List<IReadOnlyCollection<FirstDto>>> three,
AnotherDto[] four,
string five,
int[] six,
List<List<List<List<List<List<string>>>>>> seven

Thank you for reading this question.


Solution

  • I solved My problem by making the Child object nullable:

    public CsharpTypeBase? Child { get;set; }
    

    and using it like this :

    FromTypeSyntax(child, output.Child ??= new());