diff --git a/Directory.Build.targets b/Directory.Build.targets
index 4ea6948a..25de2311 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -16,11 +16,15 @@
+ Condition=" $(RepoRelativeProjectDir.Contains('src')) And
+ '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And
+ $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '9.0')) ">
true
@@ -112,6 +116,7 @@
$(DefineConstants);SUPPORTS_CERTIFICATE_LOADER
$(DefineConstants);SUPPORTS_JSON_ELEMENT_DEEP_EQUALS
$(DefineConstants);SUPPORTS_JSON_ELEMENT_PROPERTY_COUNT
+ $(DefineConstants);SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
filter))
+ if (_provider.GetService(descriptor.FilterTypes[index]) is not IOpenIddictClientHandlerFilter filter)
{
throw new InvalidOperationException(SR.FormatID0099(descriptor.FilterTypes[index]));
}
diff --git a/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkBuilder.cs b/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkBuilder.cs
index 963bc0ab..3daff43a 100644
--- a/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkBuilder.cs
+++ b/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkBuilder.cs
@@ -76,6 +76,15 @@ public sealed class OpenIddictEntityFrameworkBuilder
throw new InvalidOperationException(SR.GetResourceString(SR.ID0277));
}
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ // If the specified key type isn't a string (which is special-cased by the stores to avoid having to resolve
+ // a TypeDescriptor instance) and the platform supports type registration, register the key type to ensure the
+ // TypeDescriptor associated with that type will be preserved by the IL Linker and can be resolved at runtime.
+ if (typeof(TKey) != typeof(string))
+ {
+ TypeDescriptor.RegisterType();
+ }
+#endif
Services.Replace(ServiceDescriptor.Scoped(static provider =>
provider.GetRequiredService>()));
Services.Replace(ServiceDescriptor.Scoped(static provider =>
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs
index 0354914f..03a6baee 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs
@@ -1174,11 +1174,23 @@ public class OpenIddictEntityFrameworkApplicationStore<
return default;
}
- return (TKey?) GetConverter().ConvertFromInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (typeof(TKey) == typeof(string))
+ {
+ return (TKey?) (object?) identifier;
+ }
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
+
+ return (TKey?) converter.ConvertFromInvariantString(identifier);
+ }
}
///
@@ -1193,10 +1205,22 @@ public class OpenIddictEntityFrameworkApplicationStore<
return null;
}
- return GetConverter().ConvertToInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (identifier is string value)
+ {
+ return value;
+ }
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
+
+ return converter.ConvertToInvariantString(identifier);
+ }
}
}
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs
index c20665c0..2aab67fa 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs
@@ -975,11 +975,23 @@ public class OpenIddictEntityFrameworkAuthorizationStore<
return default;
}
- return (TKey?) GetConverter().ConvertFromInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (typeof(TKey) == typeof(string))
+ {
+ return (TKey?) (object?) identifier;
+ }
+
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ return (TKey?) converter.ConvertFromInvariantString(identifier);
+ }
}
///
@@ -994,10 +1006,22 @@ public class OpenIddictEntityFrameworkAuthorizationStore<
return null;
}
- return GetConverter().ConvertToInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (identifier is string value)
+ {
+ return value;
+ }
+
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ return converter.ConvertToInvariantString(identifier);
+ }
}
}
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs
index c93d7e19..67da8668 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs
@@ -758,11 +758,23 @@ public class OpenIddictEntityFrameworkScopeStore<
return default;
}
- return (TKey?) GetConverter().ConvertFromInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (typeof(TKey) == typeof(string))
+ {
+ return (TKey?) (object?) identifier;
+ }
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
+
+ return (TKey?) converter.ConvertFromInvariantString(identifier);
+ }
}
///
@@ -777,10 +789,22 @@ public class OpenIddictEntityFrameworkScopeStore<
return null;
}
- return GetConverter().ConvertToInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (identifier is string value)
+ {
+ return value;
+ }
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
+
+ return converter.ConvertToInvariantString(identifier);
+ }
}
}
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs
index c86f9b76..1d33f790 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs
@@ -1139,11 +1139,23 @@ public class OpenIddictEntityFrameworkTokenStore<
return default;
}
- return (TKey?) GetConverter().ConvertFromInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (typeof(TKey) == typeof(string))
+ {
+ return (TKey?) (object?) identifier;
+ }
+
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ return (TKey?) converter.ConvertFromInvariantString(identifier);
+ }
}
///
@@ -1158,10 +1170,22 @@ public class OpenIddictEntityFrameworkTokenStore<
return null;
}
- return GetConverter().ConvertToInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (identifier is string value)
+ {
+ return value;
+ }
+
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ return converter.ConvertToInvariantString(identifier);
+ }
}
}
diff --git a/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreBuilder.cs b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreBuilder.cs
index 8c3c05f5..1aeb2e61 100644
--- a/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreBuilder.cs
+++ b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreBuilder.cs
@@ -89,6 +89,15 @@ public sealed class OpenIddictEntityFrameworkCoreBuilder
where TToken : OpenIddictEntityFrameworkCoreToken
where TKey : notnull, IEquatable
{
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ // If the specified key type isn't a string (which is special-cased by the stores to avoid having to resolve
+ // a TypeDescriptor instance) and the platform supports type registration, register the key type to ensure the
+ // TypeDescriptor associated with that type will be preserved by the IL Linker and can be resolved at runtime.
+ if (typeof(TKey) != typeof(string))
+ {
+ TypeDescriptor.RegisterType();
+ }
+#endif
Services.Replace(ServiceDescriptor.Scoped(static provider =>
provider.GetRequiredService>()));
Services.Replace(ServiceDescriptor.Scoped(static provider =>
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs
index 14f95a9b..c83a57c0 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs
@@ -1255,11 +1255,23 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
return default;
}
- return (TKey?) GetConverter().ConvertFromInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (typeof(TKey) == typeof(string))
+ {
+ return (TKey?) (object?) identifier;
+ }
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
+
+ return (TKey?) converter.ConvertFromInvariantString(identifier);
+ }
}
///
@@ -1274,10 +1286,22 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
return null;
}
- return GetConverter().ConvertToInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (identifier is string value)
+ {
+ return value;
+ }
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
+
+ return converter.ConvertToInvariantString(identifier);
+ }
}
}
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs
index b579bda8..9b6dbf13 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs
@@ -1182,11 +1182,23 @@ public class OpenIddictEntityFrameworkCoreAuthorizationStore<
return default;
}
- return (TKey?) GetConverter().ConvertFromInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (typeof(TKey) == typeof(string))
+ {
+ return (TKey?) (object?) identifier;
+ }
+
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ return (TKey?) converter.ConvertFromInvariantString(identifier);
+ }
}
///
@@ -1201,10 +1213,22 @@ public class OpenIddictEntityFrameworkCoreAuthorizationStore<
return null;
}
- return GetConverter().ConvertToInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (identifier is string value)
+ {
+ return value;
+ }
+
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ return converter.ConvertToInvariantString(identifier);
+ }
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs
index c2d12419..edc48274 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs
@@ -772,11 +772,23 @@ public class OpenIddictEntityFrameworkCoreScopeStore<
return default;
}
- return (TKey?) GetConverter().ConvertFromInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (typeof(TKey) == typeof(string))
+ {
+ return (TKey?) (object?) identifier;
+ }
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
+
+ return (TKey?) converter.ConvertFromInvariantString(identifier);
+ }
}
///
@@ -791,10 +803,22 @@ public class OpenIddictEntityFrameworkCoreScopeStore<
return null;
}
- return GetConverter().ConvertToInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (identifier is string value)
+ {
+ return value;
+ }
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
+
+ return converter.ConvertToInvariantString(identifier);
+ }
}
}
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs
index 365fa936..75072617 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs
@@ -1342,11 +1342,23 @@ public class OpenIddictEntityFrameworkCoreTokenStore<
return default;
}
- return (TKey?) GetConverter().ConvertFromInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (typeof(TKey) == typeof(string))
+ {
+ return (TKey?) (object?) identifier;
+ }
+
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ return (TKey?) converter.ConvertFromInvariantString(identifier);
+ }
}
///
@@ -1361,10 +1373,22 @@ public class OpenIddictEntityFrameworkCoreTokenStore<
return null;
}
- return GetConverter().ConvertToInvariantString(identifier);
+ // Optimization: if the key is a string, directly return it as-is.
+ if (identifier is string value)
+ {
+ return value;
+ }
+
+ else
+ {
+ var converter =
+#if SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
+ TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey));
+#else
+ TypeDescriptor.GetConverter(typeof(TKey));
+#endif
- [UnconditionalSuppressMessage("Trimming", "IL2026",
- Justification = "Only primitive types are supported as entity keys.")]
- static TypeConverter GetConverter() => TypeDescriptor.GetConverter(typeof(TKey));
+ return converter.ConvertToInvariantString(identifier);
+ }
}
}
diff --git a/src/OpenIddict.Server/OpenIddictServerDispatcher.cs b/src/OpenIddict.Server/OpenIddictServerDispatcher.cs
index 436f6f0f..d3ed305f 100644
--- a/src/OpenIddict.Server/OpenIddictServerDispatcher.cs
+++ b/src/OpenIddict.Server/OpenIddictServerDispatcher.cs
@@ -121,7 +121,7 @@ public sealed class OpenIddictServerDispatcher : IOpenIddictServerDispatcher
{
for (var index = 0; index < descriptor.FilterTypes.Length; index++)
{
- if (!(_provider.GetService(descriptor.FilterTypes[index]) is IOpenIddictServerHandlerFilter filter))
+ if (_provider.GetService(descriptor.FilterTypes[index]) is not IOpenIddictServerHandlerFilter filter)
{
throw new InvalidOperationException(SR.FormatID0099(descriptor.FilterTypes[index]));
}
diff --git a/src/OpenIddict.Validation/OpenIddictValidationDispatcher.cs b/src/OpenIddict.Validation/OpenIddictValidationDispatcher.cs
index e5fa2366..f7193a15 100644
--- a/src/OpenIddict.Validation/OpenIddictValidationDispatcher.cs
+++ b/src/OpenIddict.Validation/OpenIddictValidationDispatcher.cs
@@ -121,7 +121,7 @@ public sealed class OpenIddictValidationDispatcher : IOpenIddictValidationDispat
{
for (var index = 0; index < descriptor.FilterTypes.Length; index++)
{
- if (!(_provider.GetService(descriptor.FilterTypes[index]) is IOpenIddictValidationHandlerFilter filter))
+ if (_provider.GetService(descriptor.FilterTypes[index]) is not IOpenIddictValidationHandlerFilter filter)
{
throw new InvalidOperationException(SR.FormatID0099(descriptor.FilterTypes[index]));
}