L'accès à un Constructeur Privé de l'Extérieur de la Classe en C#
Si je définir une classe avec un constructeur par défaut et un constructeur public qui a des paramètres, comment puis-je accéder au constructeur privé?
public class Bob
{
public String Surname { get; set; }
private Bob()
{ }
public Bob(string surname)
{
Surname = surname;
}
}
Je peux accéder au constructeur privé via une méthode statique de la classe comme ceci:
public static Bob GetBob()
{
return new Bob();
}
J'ai pensé que je pouvais accéder au constructeur privé via une méthode d'extension, puisque (selon ma compréhension) les méthodes d'extension sont convertis afin qu'ils semblent être méthodes statiques de la classe, mais je ne peux pas:
static class Fred
{
public static Bob Bobby(this Bob bob)
{
return new Bob();
}
}
Alors, comment puis-je accéder au constructeur privé?
Merci
EDIT:
La raison que j'ai voulu faire ce que je voulais créer des tests pour l'un de nos classes, mais de ne pas permettre à un consommateur de cette classe pour pouvoir instancier un objet de manière incorrecte. Je suis en essais, donc je sais (j'espère!) dans quelles circonstances les tests échouent. Je suis encore un test de n00b maintenant donc, mon idée peut ou peut ne pas avoir été dans le "mauvais sens" de faire les choses.
J'ai changé ma stratégie de test pour juste faire les choses de la façon dont les consommateurs de cette classe, c'est à dire d'appeler les méthodes publiques et si les méthodes publiques sont OK, en supposant que les méthodes privées sont OK. Je préfère encore de tester les méthodes privées, mais mon patron est respirer en bas de mon cou sur un produit livrable 🙁
- L'humour moi, Pourquoi voulez-vous appeler votre constructeur à l'extérieur de votre implémentation de la classe ?
- Pourquoi le vote serré? C'est encore une question valable, même si il n'est pas recommandé pour obtenir le constructeur.
- D'accord-encore une question, pourquoi fermer?
- Re: Essai des méthodes privées. J'ai trouvé que par des essais privés méthodes individuellement, mes tests sont plus petits et plus précis que si je ne tester que les méthodes publiques. J'ai tendance à faire de "privé" en "protégés" et écrivez un gestionnaire spécifique de la classe dans la bibliothèque de test pour les exposer comme des versions publiques plutôt que d'utiliser la réflexion.
- Herbi, Votre classe plus de chances d'avoir quelques odeurs de code si vos méthodes de test obtenir de gros pour être en mesure de tester privé/protégé méthodes.
- Oui, beaucoup de l'héritage du code écrit par d'anciens développeurs. De Plus, je dois dire que l'entreprise en cause la logique (la partie échange de chiffre d'affaires) est ridiculement compliqué (plus complexe que mon Doctorat pour un début), mais c'est la façon dont nos clients.
- Je ne peux imaginer une raison pour un privé ctor. Ok, objet de la piscine de modèle et d'obtenir de l'instance, mais même là, je le ferais protégé. Donc, est-il une raison pour un privé ctor à tous?
Vous devez vous connecter pour publier un commentaire.
Constructeurs par défaut sont privés pour une raison. Le développeur n'est pas privé pour le plaisir.
Mais si vous voulez continuer à utiliser le constructeur par défaut que vous obtenez par l'aide de la réflexion.
Modifier
J'ai vu votre commentaire sur le test. Ne jamais tester protected ou private méthodes /propriétés. Vous avez probablement fait quelque chose de mal si vous ne pouvez pas gérer à tester ces méthodes/propriétés par le biais de l'API publique. Soit de les supprimer ou de refactoriser la classe.
Edit 2
Oublié une liaison drapeau.
GetConstructor
méthode renvoie la valeur nulle, de sorte que le code renvoie une exception NullReferenceException.typeof(Bob).GetConstructors(BindingFlags.NonPublic);
renvoie un tableau vide.o => new MyImmutableObject(o.Name, o.Description)
ào => new MyImmutableObject() { o.Name, o.Description}
, sans avoir à sacrifier l'immuabilité ailleurs (le constructeur par défaut est "privé"). Merci à vous pour mettre en garde contre elle, mais je vous remercie doublement pour répondre à toute façon.Il y a plusieurs façons de contourner ce problème:
Un: Faire le constructeur public. Si vous avez besoin d'y accéder à partir de l'extérieur de la classe pourquoi est-il privé (c'est peut être que vous ne voulez accéder au constructeur privé pour le test, dans lequel cas, c'est une question valable).
Deux: Faire le constructeur protégé, l'accès au travers d'une classe dérivée:
Trois: Utiliser la réflexion (comme indiqué par jgauffin).
En plus de @jgauffin la réponse qui raconte comment appeler les constructeurs privés via la réflexion:
Est-il possible de changer les paramètres du constructeur privé?
Il me semble que vous êtes la mise en œuvre de l'Usine de Modèle dans votre code. Ainsi, le modificateur est censé être
internal
.Les méthodes d'Extension
Appel
p.DoSomething()
en fait égal àMyExt.DoSomething(p)
. Ce n'est pas cette méthode dans la classe Produit.Vous pouvez instancier les instances de ce type par la réflexion.
La méthode Bobby est toujours dans une classe différente, appelé Fred. C'est pourquoi vous ne pouvez pas accéder à la prive constructeur de la Bob de classe. Ce que vous essayez de faire n'est pas possible avec joint méthodes. Même si ils peuvent être fixés sur une autre classe, ils sont encore déclarée en dehors de la classe et suivent le champ d'application/les règles d'accès.
Bobby
montrer ce que j'ai fait en sorte que personne ne perd leur temps, ce qui suggère des méthodes d'extension.Si vous êtes en utilisant dotnet core, vous pouvez effectuer les opérations suivantes sans même avoir à jouer avec toute la réflexion: