diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs
index 267d3e89..868deba1 100644
--- a/src/Consume/Consume.cs
+++ b/src/Consume/Consume.cs
@@ -109,6 +109,7 @@ class Consume
#endif
type = typeof(AsyncMethodBuilderAttribute);
type = typeof(CompilerLoweringPreserveAttribute);
+ type = typeof(IsClosedTypeAttribute);
#if !NET6_0 && !NET5_0
type = typeof(ObsoletedOSPlatformAttribute);
type = typeof(SupportedOSPlatformGuardAttribute);
diff --git a/src/ConsumeCsPreview/ClosedHierarchy.cs b/src/ConsumeCsPreview/ClosedHierarchy.cs
new file mode 100644
index 00000000..f99fddb9
--- /dev/null
+++ b/src/ConsumeCsPreview/ClosedHierarchy.cs
@@ -0,0 +1,38 @@
+namespace ConsumeCsPreview;
+
+// Compile-only coverage for the C# `closed` modifier. The compiler emits
+// IsClosedTypeAttribute on the closed type and
+// CompilerFeatureRequiredAttribute("ClosedClasses") on its constructors,
+// so this only compiles when both are polyfilled.
+
+#region ClosedHierarchy
+
+// Only types in this file can derive from JobStatus
+closed class JobStatus;
+
+sealed class Queued : JobStatus;
+
+sealed class Running(int percentComplete) : JobStatus
+{
+ public int PercentComplete => percentComplete;
+}
+
+sealed class Failed(string error) : JobStatus
+{
+ public string Error => error;
+}
+
+static class ClosedHierarchy
+{
+ // No default arm: the switch is exhaustive because every direct descendant of
+ // the closed JobStatus is handled. Without exhaustiveness this warns CS8509.
+ public static string Describe(JobStatus status) =>
+ status switch
+ {
+ Queued => "queued",
+ Running running => $"{running.PercentComplete}% complete",
+ Failed failed => $"failed: {failed.Error}"
+ };
+}
+
+#endregion
diff --git a/src/ConsumeCsPreview/ConsumeCsPreview.csproj b/src/ConsumeCsPreview/ConsumeCsPreview.csproj
new file mode 100644
index 00000000..0b4b7ab8
--- /dev/null
+++ b/src/ConsumeCsPreview/ConsumeCsPreview.csproj
@@ -0,0 +1,20 @@
+
+
+ $(NoWarn);PolyfillTargetsForNuget
+ true
+ preview
+ net461;net462;net47;net471;net472;net48;net481;net6.0-windows
+ $(TargetFrameworks);netstandard2.0;netstandard2.1;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0;net11.0
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Polyfill.slnx b/src/Polyfill.slnx
index 621fc120..aa8c9d42 100644
--- a/src/Polyfill.slnx
+++ b/src/Polyfill.slnx
@@ -29,6 +29,7 @@
+
diff --git a/src/Polyfill/IsClosedTypeAttribute.cs b/src/Polyfill/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..500de7be
--- /dev/null
+++ b/src/Polyfill/IsClosedTypeAttribute.cs
@@ -0,0 +1,40 @@
+#if !NET11_0_OR_GREATER
+
+namespace System.Runtime.CompilerServices;
+
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+//Link: https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.isclosedtypeattribute?view=net-11.0
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
+
+#else
+[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.IsClosedTypeAttribute))]
+#endif
diff --git a/src/Split/net10.0/IsClosedTypeAttribute.cs b/src/Split/net10.0/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/net10.0/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/net11.0/TypeForwardeds.cs b/src/Split/net11.0/TypeForwardeds.cs
index f93df98b..435914d1 100644
--- a/src/Split/net11.0/TypeForwardeds.cs
+++ b/src/Split/net11.0/TypeForwardeds.cs
@@ -18,6 +18,7 @@
[assembly: TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.FeatureGuardAttribute))]
[assembly: TypeForwardedTo(typeof(System.Diagnostics.CodeAnalysis.FeatureSwitchDefinitionAttribute))]
[assembly: TypeForwardedTo(typeof(System.Collections.Generic.IAlternateEqualityComparer<,>))]
+[assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.IsClosedTypeAttribute))]
[assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.IsExternalInit))]
[assembly: TypeForwardedTo(typeof(System.Collections.Generic.KeyValuePair))]
[assembly: TypeForwardedTo(typeof(System.Threading.Lock))]
diff --git a/src/Split/net461/IsClosedTypeAttribute.cs b/src/Split/net461/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/net461/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/net462/IsClosedTypeAttribute.cs b/src/Split/net462/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/net462/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/net47/IsClosedTypeAttribute.cs b/src/Split/net47/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/net47/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/net471/IsClosedTypeAttribute.cs b/src/Split/net471/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/net471/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/net472/IsClosedTypeAttribute.cs b/src/Split/net472/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/net472/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/net48/IsClosedTypeAttribute.cs b/src/Split/net48/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/net48/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/net481/IsClosedTypeAttribute.cs b/src/Split/net481/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/net481/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/net5.0/IsClosedTypeAttribute.cs b/src/Split/net5.0/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/net5.0/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/net6.0/IsClosedTypeAttribute.cs b/src/Split/net6.0/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/net6.0/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/net7.0/IsClosedTypeAttribute.cs b/src/Split/net7.0/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/net7.0/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/net8.0/IsClosedTypeAttribute.cs b/src/Split/net8.0/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/net8.0/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/net9.0/IsClosedTypeAttribute.cs b/src/Split/net9.0/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/net9.0/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/netcoreapp2.0/IsClosedTypeAttribute.cs b/src/Split/netcoreapp2.0/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/netcoreapp2.0/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/netcoreapp2.1/IsClosedTypeAttribute.cs b/src/Split/netcoreapp2.1/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/netcoreapp2.1/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/netcoreapp2.2/IsClosedTypeAttribute.cs b/src/Split/netcoreapp2.2/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/netcoreapp2.2/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/netcoreapp3.0/IsClosedTypeAttribute.cs b/src/Split/netcoreapp3.0/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/netcoreapp3.0/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/netcoreapp3.1/IsClosedTypeAttribute.cs b/src/Split/netcoreapp3.1/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/netcoreapp3.1/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/netstandard2.0/IsClosedTypeAttribute.cs b/src/Split/netstandard2.0/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/netstandard2.0/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/netstandard2.1/IsClosedTypeAttribute.cs b/src/Split/netstandard2.1/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/netstandard2.1/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}
diff --git a/src/Split/uap10.0/IsClosedTypeAttribute.cs b/src/Split/uap10.0/IsClosedTypeAttribute.cs
new file mode 100644
index 00000000..ad49e22f
--- /dev/null
+++ b/src/Split/uap10.0/IsClosedTypeAttribute.cs
@@ -0,0 +1,32 @@
+//
+#pragma warning disable
+namespace System.Runtime.CompilerServices;
+using Diagnostics;
+using Diagnostics.CodeAnalysis;
+///
+/// Reserved for use by a compiler for tracking metadata.
+/// This attribute should not be used by developers in source code.
+///
+[ExcludeFromCodeCoverage]
+[DebuggerNonUserCode]
+[AttributeUsage(AttributeTargets.Class, Inherited = false)]
+#if PolyUseEmbeddedAttribute
+[global::Microsoft.CodeAnalysis.EmbeddedAttribute]
+#endif
+#if PolyPublic
+public
+#endif
+sealed class IsClosedTypeAttribute :
+ Attribute
+{
+ Type[] derivedTypes = Type.EmptyTypes;
+ ///
+ /// Gets or sets the derived types of the closed type.
+ /// A value is normalized to an empty array.
+ ///
+ public Type[] DerivedTypes
+ {
+ get => derivedTypes;
+ set => derivedTypes = value ?? Type.EmptyTypes;
+ }
+}