web-dev-qa-db-fra.com

Le type '...' n'a pas de constructeur défini

Je remarque une erreur du compilateur Le type '...' n'a pas de constructeur défini généré lorsque je tente par erreur d'instancier une classe de particlar.

Cela me conduit à me demander comment j'écrirais ma propre classe qui précipiterait ce message quand quelqu'un tenterait de l'instancier. 

Donc, le code ci-dessous, que dois-je faire pour MyClass?

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

    class MyClass
    {
        MyClass()
        {
        }
    }
}
39
James Wiseman

Cette erreur ( CS0143 ) se produit si la classe définit uniquement un constructeur internal et que vous essayez de l'instancier à partir d'un autre assembly.

public class MyClass
{
    internal MyClass()
    {
    }
}
42
Frédéric Hamidi

De plus, cette erreur peut être la cause si vous compilez avec Framework 4 ou supérieur et intégrez les types d'interopérabilité dans votre assembly géré. Pour vous débarrasser de cette erreur, vous devez désactiver (pas incorporer) les types d'interopérabilité incorporés.

Instructions pour désactiver l'intégration:

  1. Dans VS2010 Solution Explorer, cliquez avec le bouton droit sur la référence d'interopérabilité que vous utilisez.
  2. Sélectionnez Propriétés et cherchez Embed Interop Types
  3. Changez-le de True à False

Vous pouvez en savoir plus sur les types d'interopérabilité incorporés ici .

Pablo

25
Pabinator

J'ai réussi à reproduire ceci en:

  • Création d'une classe statique dans une DLL
  • Utiliser ildasm pour le décompiler en IL
  • Modification de l'IL pour supprimer les modificateurs "abstract" et "sealed" de la classe
  • Reconstruction de la DLL avec ilasm
  • Compiler un programme qui tente de créer une instance de la classe

Si vous ne supprimez pas les modificateurs abstract/sealed, le compilateur C # les reconnaît en tant que classe statique et envoie un message d'erreur différent. Bien sûr, vous pouvez commencer avec un type "normal" et simplement supprimer les constructeurs.

EDIT: Je pensais en fait que je n’avais pas soumis cela, car j’avais vu en premier le constructeur "interne". Cependant, je vais le laisser maintenant car ma version rend le compilateur C # correct - il y a une différence entre un type n'ayant pas de constructeur accessible et véritablement n'ayant pas de constructeur :)

11
Jon Skeet

Je crois que vous auriez besoin de rendre le constructeur de la classe interne afin de lui permettre de lever cette exception. Je crois que vous aurez également besoin de la classe pour exister dans une autre Assemblée.

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

namespace DifferentNamespace
{
   class MyClass
   {
      internal MyClass()
      {
      }
   }
}
5
Brian Dishaw

Encore une autre option: le code a peut-être raison, mais vous pouvez travailler sur différents projets dans différentes instances de Visual Studio et vous devez donc créer le projet référencé en premier. 

0
Br2