How to Resolve Error "CS0824: Constructor 'name' is marked external" in C#
The Compiler Warning CS0824 indicates a potential runtime issue with object creation. The message reads: "Constructor 'ClassName' is marked external".
In C#, the extern modifier indicates that a method or constructor is implemented externally (usually in unmanaged code like C++ or by the runtime itself). While this is common for static methods using [DllImport], applying extern to a constructor is unusual and risky. The compiler issues this warning because it cannot verify that the external implementation actually exists. If the runtime fails to find the implementation when you try to create an object (new ClassName()), the application will crash.
This guide explains when this warning appears and how to handle it correctly.
Understanding External Constructors
When a constructor is marked extern, you are telling the compiler: "Don't generate any code for this. The Common Language Runtime (CLR) or an external DLL will handle the object creation logic."
This is valid in very specific scenarios:
- COM Interop: When manually defining a wrapper for a COM object (
[ComImport]). - Internal Runtime Types: Core .NET types (like
StringorArray) sometimes use this for internal magic.
For standard application development, you almost never want an extern constructor because C# does not support importing C++ class constructors directly.
Scenario 1: Using extern as a Placeholder (Mistake)
Developers sometimes misuse extern when they want to declare a constructor but don't want to write the implementation body yet (similar to an abstract method or interface). Or, they might mistakenly believe this is how to import a C++ class constructor.
Example of error
public class MyService
{
// ⛔️ Warning CS0824: Constructor 'MyService' is marked external.
// The compiler warns: "I will let you compile this, but if you try to
// call 'new MyService()', it will likely crash at runtime."
public extern MyService();
}
class Program
{
static void Main()
{
// This will throw a System.MissingMethodException at runtime
var s = new MyService();
}
}
Solution: Use throw new NotImplementedException
If you are just stubbing out code, give the constructor a body that throws an exception. Do not use extern.
using System;
public class MyService
{
// ✅ Correct: Defines the constructor but indicates it's not ready.
public MyService()
{
throw new NotImplementedException("TODO: Implement this constructor");
}
}
If you were trying to import a C++ constructor, note that P/Invoke ([DllImport]) only supports static functions. You cannot directly map a C++ instance constructor to a C# extern constructor. You usually need a C++ "Factory" function exported as static and wrapped in C#.
Scenario 2: COM Interoperability (Valid Use Case)
The primary valid use case for an extern constructor is when you are manually writing an Interop class to communicate with a COM library, and you have marked the class with [ComImport].
In this case, the runtime does know how to create the object (via the GUID), so the code works, but the compiler still emits the warning out of caution.
The Code with Warning
using System.Runtime.InteropServices;
[ComImport]
[Guid("00000000-0000-0000-0000-000000000000")] // Example GUID
[CoClass(typeof(MyComClass))]
public interface IMyComInterface
{
}
public class MyComClass
{
// ⛔️ Warning CS0824: The compiler generates this warning even for valid COM imports.
public extern MyComClass();
}
Solution: Suppress the Warning
If you are certain that the class is a valid COM Import and the runtime will handle the creation successfully, you can safely suppress this specific warning.
using System.Runtime.InteropServices;
// ... interface definitions ...
public class MyComClass
{
// ✅ Correct: We acknowledge the external nature and suppress the noise.
#pragma warning disable CS0824
public extern MyComClass();
#pragma warning restore CS0824
}
Conclusion
CS0824 is a "Proceed with Caution" sign.
- Check your Intent: Are you just trying to leave the body empty?
- Yes: Remove
externand use{ }orthrow new NotImplementedException().
- Yes: Remove
- Check Interop: Are you doing COM Interop?
- Yes: Ensure the class has
[ComImport]and[Guid], then suppress the warning with#pragma.
- Yes: Ensure the class has
- Check C++ Imports: Are you trying to import a C++ class?
- Yes: This syntax won't work. Use a static Factory method with
[DllImport]instead.
- Yes: This syntax won't work. Use a static Factory method with