Skip to main content

How to Resolve Error "CS0648: 'type' is a type not supported by the language" in C#

The Compiler Error CS0648 is an interoperability error. The message reads: " 'Type' is a type not supported by the language".

The .NET Common Language Runtime (CLR) supports a wider range of features than the C# language itself explicitly exposes. This error occurs when your C# project references a library written in another language (like C++/CLI, VB.NET, or IL assembly) that exposes a type or member using features C# does not understand. Common culprits include Named Indexed Properties, exotic C++ templates, or unsupported runtime primitives.

This guide explains how to identify these unsupported types and workaround them using accessor methods or reflection.

Understanding the CLR Gap

C# is just one language that runs on .NET.

  • C# uses this[index] for indexers. It does not allow properties to have arguments (e.g., obj.Property[index]).
  • VB.NET allows Named Indexed Properties (e.g., Public ReadOnly Property Data(i As Integer)).
  • C++/CLI allows complex modifiers (modopt, modreq) on types.

If you reference a DLL created in VB.NET or C++ that exposes these features publicly, the C# compiler can see them in the metadata but refuses to let you use them because it has no syntax to represent them.

Scenario 1: Named Indexed Properties (Interop/VB.NET)

This is the most common cause, often seen when interacting with COM libraries (like Office Interop) or legacy VB.NET binaries.

C# expects a property to be a value. It does not expect a property to require an argument list immediately after the property name (unless it is the default this[] indexer).

Example of error

Imagine a library (ThirdParty.dll) written in another language that has a property Items which takes an index.

public class InteropWrapper
{
public void ReadData(ThirdPartyObject obj)
{
// ⛔️ Error CS0648 (or related syntax errors):
// C# thinks 'Items' is a property returning a collection.
// But in the DLL, 'Items' expects arguments directly.
var item = obj.Items[0];
}
}

Solution: Use Accessor Methods

Under the hood, properties are just methods (get_Name and set_Name). Even if C# cannot support the property syntax, it can almost always see the underlying methods.

You can often call the getter method directly.

public class InteropWrapper
{
public void ReadData(ThirdPartyObject obj)
{
// ✅ Correct: Bypass the property syntax and call the getter method directly.
// This method is generated by the CLR for the indexed property.
var item = obj.get_Items(0);
}
}
note

Dynamic Keyword: If the library supports it, using dynamic can sometimes bypass compiler checks and resolve the call at runtime: dynamic d = obj; var item = d.Items[0];

Scenario 2: Unsupported Runtime Types

Some types in the System namespace are reserved for the runtime's internal use and are not meant to be exposed in C# code. If a third-party library exposes these types as public fields or return values, C# will flag them as unsupported.

Examples include:

  • System.Void (used as a return type reflection, but not a valid variable type).
  • System.RuntimeArgumentHandle (used for __arglist).
  • System.ArgIterator (on older platforms or specific contexts).

Example of error

public class RuntimeTest
{
// ⛔️ Error CS0648: 'void' is not a valid type for a field.
// While you can write 'void Method()', you cannot use System.Void as a variable.
public System.Void MyField;
}

Solution

There is no direct fix if a library forces you to use such a type. You must usually avoid accessing that specific member. If you are defining it yourself: stop. Use object, IntPtr, or standard types.

Solution: Using Reflection

If a third-party library exposes a type that C# absolutely refuses to compile (e.g., a C++ type with unsupported modifiers), you can use Reflection to interact with it indirectly. This bypasses the compiler's strict type checking.

Solution:

using System.Reflection;

public class MagicInterop
{
public void ProcessUnknown(object externalObj)
{
// Suppose externalObj has a field of an unsupported type.
// We cannot write: var x = externalObj.BadField;

// ✅ Correct: Use Reflection to get the value as a generic 'object'
PropertyInfo prop = externalObj.GetType().GetProperty("SomeProperty");
object value = prop.GetValue(externalObj);

System.Console.WriteLine(value); // We can print it or pass it along
}
}

Conclusion

CS0648 means you have encountered a boundary of the C# language.

  1. Check Interop: Are you using a VB.NET or C++ DLL?
  2. Look for Methods: If the error happens on a property obj.Prop, look for obj.get_Prop().
  3. Use Dynamic/Reflection: If the static compiler blocks you, move the resolution to runtime using dynamic or System.Reflection.