louthy/language-ext · error · ArgumentException

Constructor not found for type

Error message

Constructor not found for type {typeof(R).FullName}

What it means

IL.Ctor<R>() builds a compiled delegate that instantiates R via its parameterless constructor, emitting DynamicMethod IL for speed. Before emitting, it looks up the constructor with GetConstructor<R>(); if the type has no accessible parameterless constructor, it throws ArgumentException with the type's FullName. This library throws it because IL emission requires a concrete ConstructorInfo to generate the call.

Solutions

  1. Add a public parameterless constructor to R, or call the IL.Ctor overload matching the actual constructor arity (e.g. IL.Ctor<A, R> for one argument).
  2. If R cannot be changed, switch to Activator.CreateInstance<R>() or a factory lambda () => new R(...) instead of IL emission.
  3. Verify R is a concrete, non-abstract, non-interface type with an accessible (public) parameterless constructor before calling IL.Ctor<R>().

Example fix

// before
var make = IL.Ctor<Person>(); // Person has no parameterless ctor
// after
var make = IL.Ctor<string, int, Person>(); // matches Person(string, int)
Defensive patterns

Strategy: validation

Validate before calling

if (typeof(R).IsInterface || typeof(R).IsAbstract ||
    R.GetConstructors().All(c => c.GetParameters().Length != 0))
    throw new InvalidOperationException(
        $"{typeof(R).FullName} has no public parameterless constructor; cannot use IL.Ctor<R>()");

Type guard

static bool HasParameterlessCtor<R>() =>
    !typeof(R).IsInterface && !typeof(R).IsAbstract &&
    typeof(R).GetConstructor(Type.EmptyTypes) != null;

Try / catch

Func<R> make;
try { make = IL.Ctor<R>(); }
catch (ArgumentException ex) when (ex.Message.Contains("Constructor not found"))
{
    make = () => Activator.CreateInstance<R>(); // or another fallback
}

Prevention

When it happens

Trigger: Calling IL.Ctor<R>() where typeof(R) has no public parameterless constructor — e.g. R is a record/class whose only constructors take parameters, R is an interface or abstract class, R is a struct with no explicit default ctor path matching the lookup, or the matching ctor is non-public.

Common situations: Refactoring a type used with IL.Ctor to add constructor parameters without updating call sites; mapping via LanguageExt utilities over types with required arguments; using types from assemblies trimmed of ctors; accidentally pointing Ctor<T>() at an interface or abstract base type.

Related errors


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

Appendix: source

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

using System.Reflection.Emit;
using System.Runtime.Serialization;
using System.Text;
using LanguageExt.Traits.Resolve;
using static LanguageExt.Prelude;
using static LanguageExt.Reflect;

namespace LanguageExt;

public static class IL
{
    /// <summary>
    /// Emits the IL to instantiate a type of R with a single argument to 
    /// the constructor
    /// </summary>
    public static Func<R> Ctor<R>()
    {
        var ctorInfo = GetConstructor<R>()
           .IfNone(() => throw new ArgumentException($"Constructor not found for type {typeof(R).FullName}"));

        var dynamic = new DynamicMethod("CreateInstance",
                                        ctorInfo.DeclaringType,
                                        Type.EmptyTypes,
                                        typeof(R).Module,
                                        true);

        var il = dynamic.GetILGenerator();
        il.Emit(OpCodes.Newobj, ctorInfo);
        il.Emit(OpCodes.Ret);

        return (Func<R>)dynamic.CreateDelegate(typeof(Func<R>));
    }

    /// <summary>
    /// Emits the IL to instantiate a type of R with a single argument to 
    /// the constructor
    /// </summary>

View on GitHub (pinned to 2f0e362824)