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
- Make the generic argument match the class itself: class Foo : MultiValueConverterBase<Foo>.
- If a subclass is intended, switch to inheriting the concrete base converter class instead of MultiValueConverterBase.
- 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
- Always write MultiValueConverterBase<ThisClassName>
- Update the generic argument when renaming a converter class
- Avoid subclassing concrete converters through MultiValueConverterBase indirectly
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
- The generic argument of this class must be the type being…
- A dependency object must be attached in order to register a…
- A dependency object must be attached in order to unregister…
- Can't change the parent of this folder
- Converter is not null but previous Converter was null
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)