41

I'm noticing the compiler error The type '...' has no constructors defined generated when I erroneously attempt to instantiate a particlar class.

It lead me to wonder how I would go about writing my own class that would precipitate this message when someone attempted to instantiate it.

So the code below, what do I need to do to MyClass?

namespace MyNamespace
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass mc = new MyClass();
        }
    }

    class MyClass
    {
        MyClass()
        {
        }
    }
}
James Wiseman
  • 29,946
  • 17
  • 95
  • 158
  • Note: if you see this error when inheriting from a class (instead of directly instantiating one) - see https://stackoverflow.com/questions/22857781/inherit-an-abstract-class-without-any-constructor – Alexei Levenkov Jun 14 '17 at 16:52

6 Answers6

42

This error (CS0143) occurs if the class only defines an internal constructor and you try to instantiate it from another assembly.

public class MyClass
{
    internal MyClass()
    {
    }
}
Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
  • That's it! The key bit of info here was 'instantiate it from another assembly' I was trying the `internal` keyword in the same namespace, then a different namespace, and still nothing. This now makes sense. Cheers! – James Wiseman Aug 05 '11 at 15:07
  • What if it was in a namespace with the same name in a different assembly, or can you not do that? – James Wiseman Aug 05 '11 at 15:19
  • 1
    @James, the caller can indeed reside in a namespace with the same name, but that wouldn't change anything. The constructor would still be `internal`, and the `internal` boundary is the assembly, not the namespace. – Frédéric Hamidi Aug 05 '11 at 15:25
  • Durp, indeed, my constructor was internal and I didn't notice. Thanks! – neminem Apr 26 '13 at 18:10
25

Also this error could be cause if you are compiling with Framework 4 or higher and embedding the Interop Types into your managed assembly. To get rid of this error you need to turn off (No embed) the Embedded Interop Types.

Instructions to turn off embedding:

  1. On VS2010 Solution Explorer, right click on the Interop Reference that you are using.
  2. Select Properties and look for Embed Interop Types
  3. Change it from True to False

You can read about Embedded Interop Types here.

Pablo

Pabinator
  • 1,601
  • 1
  • 21
  • 25
12

I've managed to reproduce this by:

  • Creating a static class in a DLL
  • Using ildasm to decompile it to IL
  • Editing the IL to remove the "abstract" and "sealed" modifiers from the class
  • Rebuilding the DLL with ilasm
  • Compiling a program which tries to create an instance of the class

If you don't remove the abstract/sealed modifiers, the C# compiler recognizes it as a static class and gives a different error message. Of course, you could start off with a "normal" type and just remove the constructors, too.

EDIT: I actually thought I hadn't submitted this, as I saw the "internal" constructor one first. However, I'll leave it now as my version makes the C# compiler correct - there's a difference between a type having no accessible constructors and genuinely having no constructors :)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
5

I believe you would need to make the constructor of the class internal in order to have it throw this exception. I believe you'll also need the class to exist in another assembly.

namespace MyNamespace
{ 
   class Program
   {
       static void Main(string[] args)
       {
           MyClass mc = new MyClass();
       }
   }
}

namespace DifferentNamespace
{
   class MyClass
   {
      internal MyClass()
      {
      }
   }
}
Brian Dishaw
  • 5,767
  • 34
  • 49
3

As has been said, you can get CS0143 by trying to instantiate a class with an internal constructor from outside its assembly.

But I believe it's a compiler bug. The error generated should be CS0122:

'member' is inaccessible due to its protection level

... which is the error you get if you try to instantiate a class with only a private constructor.

CS0143 used to happen (up to C# 3.0) if you tried to call a constructor for a built-in type like Double, but in C# 4.0 that now generates CS1729:

'type' does not contain a constructor that takes 'number' arguments.

if you pass an argument

Double d = new Double(1.25);

... or no error at all if you don't pass any arguments to the constructor.

Igby Largeman
  • 16,495
  • 3
  • 60
  • 86
0

Yet another option: the code might be right, but you might work on different projects in different instances of Visual Studio, and therefore you need to build the referenced project first.

Br2
  • 167
  • 1
  • 10