louthy/language-ext · error · ArgumentException

Constructor not found for StringBuilder

Error message

Constructor not found for StringBuilder

What it means

Sentinel guard in ToStringExpr<A>: reflection lookup of the StringBuilder constructor failed while building the cached ToString expression tree for type A. It cannot fire on user input — it only means the runtime/reflection environment is broken, so expression compilation must abort.

Solutions

  1. Wrap the Show/ToString derivation in try-catch and fall back to a reflection-free default (e.g. object.ToString or a manually written formatter) when expression compilation fails.
  2. Verify the target runtime/trimming settings: linker or AOT trimming can remove StringBuilder members needed by the expression compiler, so preserve System.Text.StringBuilder via a linker descriptor or disable trimming for LanguageExt.
  3. Log the type A whose ToString lambda failed to compile so the failing case can be reproduced and given an explicit manual Show implementation.
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at LanguageExt.Core/Utility/IL.cs:779 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of louthy/language-ext@2f0e362824 (2026-09-15). Data as JSON: /api/errors/9d15f28f17d5b08c. Report an issue: GitHub.

Appendix: source

Thrown at LanguageExt.Core/Utility/IL.cs:779

                      Expression.IfThen(typesNotEqual, Expression.Return(returnTarget, Minus1))
                  }
               .Concat( Fields().Bind(identity))
               .Concat( new [] { Expression.Label(returnTarget, Zero) as Expression }));

        var lambda = Expression.Lambda<Func<A, A, int>>(block, self, other);

        return lambda.Compile();
    }

    static Func<A, string> ToStringExpr<A>(bool includeBase)
    {
        var fields = GetPublicInstanceFields<A>(
            includeBase,
            typeof(NonShowAttribute),
            typeof(NonRecordAttribute)
        ).ToArray();
            
        var stringBuilder = GetConstructor<StringBuilder>().IfNone(() => throw new ArgumentException($"Constructor not found for StringBuilder"));
        var appendChar    = GetPublicInstanceMethod<StringBuilder, char>("Append", true).IfNone(() => throw new ArgumentException($"Append method found for StringBuilder"));
        var appendString  = GetPublicInstanceMethod<StringBuilder, string>("Append", true).IfNone(() => throw new ArgumentException($"Append method found for StringBuilder"));
        var toString      = GetPublicInstanceMethod<StringBuilder>("ToString", false).IfNone(() => throw new ArgumentException($"ToString method found for StringBuilder"));
        var name          = typeof(A).Name;
        var self          = Expression.Parameter(typeof(A), "self");
        var nullA         = Expression.Constant(null, typeof(A));
        var nullStr       = Expression.Constant(null, typeof(string));
        var sb            = Expression.Variable(typeof(StringBuilder), "sb");
        var tmpStr        = Expression.Variable(typeof(string), "tmpStr");
        var result        = Expression.Variable(typeof(string), "result");
        var returnTarget  = Expression.Label(typeof(string));
            
        if (name.IndexOf('`') != -1) name = name.Split('`').AsIterable().Head.Value!;

        Expression fieldExpr(FieldInfo field)
        {
            var convertToString = (GetPublicStaticMethod(typeof(Convert), "ToString", field.FieldType) ||
                                   GetPublicStaticMethod(typeof(Convert), "ToString", typeof(object)))

View on GitHub (pinned to 2f0e362824)