stride3d/stride · error · InvalidOperationException

The generic argument of this class must be the type being…

Error message

The generic argument of this class must be the type being implemented.

What it means

MultiValueConverterBase<T> requires that the concrete class deriving from it is exactly T. This enables ProvideValue to return a new T() instance from XAML markup extension usage. If GetType() != typeof(T), the generic parameter doesn't match the implementation, and the constructor throws InvalidOperationException.

Solutions

  1. Make the generic argument match the class itself: class Foo : MultiValueConverterBase<Foo>.
  2. If a subclass is intended, switch to inheriting the concrete base converter class instead of MultiValueConverterBase.
  3. If no markup-extension instantiation is needed, inherit from a simpler base without the T self-check.

Example fix

// before
class MyConverter : MultiValueConverterBase<OtherConverter> { ... }
// after
class MyConverter : MultiValueConverterBase<MyConverter> { ... }
Defensive patterns

Strategy: validation

Validate before calling

// C# - compile-time self-check pattern
// class MyConverter : MultiValueConverterBase<MyConverter> { }  // T must equal the class name

Try / catch

try { var c = new MyConverter(); } catch (InvalidOperationException ex) { /* generic argument mismatch */ }

Prevention

When it happens

Trigger: Declaring class Foo : MultiValueConverterBase<Bar> where Bar is not Foo; copy-pasting a converter class and updating only the base type's generic argument; renaming a class without updating the generic parameter.

Common situations: Copy-paste errors when creating new converters; refactoring where the class was renamed but the generic argument still refers to the old name; accidental inheritance hierarchies (subclassing an existing converter without fixing T).

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/2a100ddda809d3af. Report an issue: GitHub.

Appendix: source

Thrown at sources/presentation/Stride.Core.Presentation.Wpf/ValueConverters/MultiValueConverterBase.cs:24

using System.Windows.Markup;

namespace Stride.Core.Presentation.ValueConverters
{
    /// <summary>
    /// An abstract class for implementations of <see cref="IMultiValueConverter"/> that supports markup extensions.
    /// </summary>
    /// <typeparam name="T">The type of <see cref="IValueConverter"/> being implemented.</typeparam>
    public abstract class MultiValueConverterBase<T> : MarkupExtension, IMultiValueConverter where T : class, IMultiValueConverter, new()
    {
        private static T valueConverterInstance;

        /// <summary>
        /// Initializes a new instance of the <see cref="ValueConverterBase{T}"/> class.
        /// </summary>
        /// <exception cref="InvalidOperationException">The generic argument does not match the type of the implementation of this class.</exception>
        protected MultiValueConverterBase()
        {
            if (GetType() != typeof(T)) throw new InvalidOperationException("The generic argument of this class must be the type being implemented.");
        }

        /// <inheritdoc/>
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return valueConverterInstance ?? (valueConverterInstance = new T());
        }

        /// <inheritdoc/>
        public abstract object Convert(object[] values, Type targetType, object parameter, CultureInfo culture);

        /// <inheritdoc/>
        public abstract object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture);
    }
}

View on GitHub (pinned to 96fad776d2)