2010-07-13 4 views

Répondre

16

Si vous parlez de contraintes génériques, oui:

class SomeContainer<T> where T : new() { 
    ... 
} 

Si vous parlez d'héritage. Il n'est pas possible d'exiger que chaque classe qui implémente votre interface ou hérite de votre classe de base possède un constructeur sans paramètre.

Le mieux que vous pouvez faire est la réflexion d'utilisation dans votre constructeur de base pour lancer une exception (à l'exécution), comme ceci:

abstract class MyBase { 
    protected MyBase() { 
     if (GetType().GetConstructor(Type.EmptyTypes) == null) 
      throw new InvalidProgramException(); 
    } 
} 

Si vous parlez d'une seule classe, oui; il suffit d'en mettre un.

1

Cela dépend de ce que vous voulez dire. Par exemple, vous pouvez contraindre un paramètre de type générique dans une classe ou une méthode à avoir un constructeur sans paramètre avec le mot-clé new, mais il n'y a pas de véritable méthode pour limiter une définition de classe réelle au-delà.

public void DoSomething<T>() where T : new() { } 
1

Comme mentionné dans la documentation MSDN officielle, le compilateur C# génère automatiquement un constructeur sans paramètre qui initialise toutes les variables membres aux valeurs par défaut. Si vous souhaitez appliquer votre propre implémentation, vous pouvez simplement faire ceci:

BaseClass classe { BaseClass() {// Mise en œuvre du constructeur parameterless} }

Si vous faites référence à des contraintes génériques, alors se référer à la publication de SLaks.

Références

http://msdn.microsoft.com/en-us/library/ace5hbzh.aspx

+2

En outre, vous pouvez forcer une classe à ne pas avoir un constructeur sans paramètre en utilisant le modificateur d'accès privé. –

+1

Les sous-classes peuvent toujours avoir un constructeur sans paramètre, même si le constructeur de la classe de base est privé, tant qu'au moins un constructeur de base est public ou protégé (ou interne si la sous-classe est dans le même assembly). –

+0

@Postman: Cela limiterait la sous-classe à toujours fournir certains paramètres au constructeur de base, mais c'est loin de "ne fonctionnera pas". –

0

J'ai rencontré un problème comme celui-ci un certain nombre de fois, je pense qu'il ya une exigence pour les constructeurs abstraits/interface. Le problème est lorsque vous utilisez Activator.CreateInstance ou une autre technique pour instancier un type que vous ne pouvez pas implémenter (IoC assez commun). La vie serait beaucoup plus facile si vous pouviez forcer un développeur à implémenter un constructeur avec les bons paramètres - même si le but est simplement de passer les params au constructeur de base. La contrainte new() a aidé le problème un peu depuis 2.0, mais elle ne résout toujours pas le problème en n'utilisant pas de génériques, ou si vous voulez des arguments spécifiques (et que vous ne voulez pas vous tromper avec les maladroits) ConstructorInfo, qui ne peut pas être vérifié de manière statique.)

2

Generics peut appliquer, mais nous ne sommes pas toujours en utilisant les médicaments génériques, p

Si vous utilisez des tests unitaires, vous pouvez utiliser la réflexion pour trouver tous les types qui répondent le modèle que vous voulez avoir constructeurs sans paramètre (par exemple, tout dérivé de MyBaseObject, ou tout dans l'espace de noms Foo.Bar), et vérifier de cette façon (par trouver le constructeur sans paramètre).

Si vous voulez aussi affirmer cela au moment de l'exécution (peut-être dans #DEBUG), des choses comme les constructeurs statiques peuvent être des points utiles pour injecter des contrôles de type supplémentaires.