How to Resolve Error "CS0733: Cannot forward generic type" in C#
The Compiler Error CS0733 is a specific error related to Type Forwarding involving Generic Types. The message reads: "Cannot forward generic type, 'GenericType<>'".
Type Forwarding ([TypeForwardedTo]) allows you to move a class from one assembly (DLL) to another without recompiling the applications that reference it. However, when forwarding Generic Types (like List<T> or MyClass<T>), the syntax must explicitly refer to the Open Generic Definition (unbound), not a specific instance of the generic type (closed).
This guide explains the correct typeof syntax required to forward generic classes.
##. Understanding Open vs. Closed Generics
When you define a generic class, it is a template.
- Open Generic (Definition):
public class Box<T> { ... }. This is the blueprint. - Closed Generic (Usage):
Box<int>,Box<string>. These are specific implementations created by the runtime.
Type Forwarding works at the Definition level. You are telling the runtime: "The blueprint for Box is no longer here; it is in NewLib.dll." You cannot tell the runtime to forward only Box<int> because Box<int> isn't a type definition in the source code; it's a runtime construction.
Scenario 1: Forwarding Closed Generics
This error occurs when a developer tries to forward a generic type by providing a placeholder type (like int or object) inside the typeof operator, thinking they need to satisfy the <T> requirement.
Example of error
Attempting to forward Container<int> instead of just Container<T>.
using System.Runtime.CompilerServices;
// ⛔️ Error CS0733: Cannot forward generic type 'Container<int>'.
// You are trying to forward a specific usage (Closed Generic).
[assembly: TypeForwardedTo(typeof(Container<int>))]
// (The actual class definition 'public class Container<T>'
// has been moved to another referenced assembly).
Solution: Use Open Generic Syntax
You must use the unbound syntax. In C#, this is represented by omitting the type name inside the angle brackets.
using System.Runtime.CompilerServices;
// ✅ Correct: The empty angle brackets '<>' represent the Open Generic Definition.
[assembly: TypeForwardedTo(typeof(Container<>))]
This syntax typeof(Container<>) tells the compiler to look for the metadata token of the generic class itself, regardless of what T eventually becomes.
Scenario 2: Syntax for Multiple Type Parameters
If your generic class has multiple parameters (e.g., Dictionary<TKey, TValue>), using empty brackets <> is not enough. You must use commas to indicate the number of parameters.
Example of error
Using simple brackets for a multi-parameter generic.
// The class being forwarded is: public class Lookup<TKey, TValue> { ... }
// ⛔️ Error (Syntax mismatch):
// The compiler might simply fail to find the type, or produce CS0733 contextually.
[assembly: TypeForwardedTo(typeof(Lookup<>))]
Solution: Add Commas
Count your generic parameters. The number of commas is Parameters - 1.
- 1 Parameter (
<T>):<> - 2 Parameters (
<T, U>):<,> - 3 Parameters (
<T, U, V>):<,,>
using System.Runtime.CompilerServices;
// ✅ Correct: The comma indicates two generic parameters.
[assembly: TypeForwardedTo(typeof(Lookup<,>))]
Conclusion
CS0733 is a syntax enforcement error regarding typeof.
- Identify the Generic: Is the class
MyClass<T>? - Check the Forwarder: Look at
[assembly: TypeForwardedTo(typeof(...))]. - Use Open Syntax:
- Do not put
int,string, orobjectinside the brackets. - Use
<>for single generics. - Use
<,>for double generics.
- Do not put