Appel Remplacé le Constructeur et le Constructeur de Base en C#
J'ai deux classes, Foo et Bar, qui possèdent des constructeurs comme ceci:
class Foo
{
Foo()
{
//do some stuff
}
Foo(int arg)
{
//do some other stuff
}
}
class Bar : Foo
{
Bar() : base()
{
//some third thing
}
}
Maintenant, je veux présenter un constructeur de Barre qui prend un int, mais je veux les trucs qui se passe dans le Bar() pour exécuter ainsi que la substance à partir de Foo(int). Quelque chose comme ceci:
Bar(int arg) : Bar(), base(arg)
{
//some fourth thing
}
Est-il possible de faire cela en C#? Le meilleur que j'ai pour l'instant est de mettre le travail effectué par une Barre() dans une fonction, qui obtient aussi appelé par une Barre(int), mais c'est assez inélégant.
Vous devez vous connecter pour publier un commentaire.
Non, ce n'est pas possible. Si vous utilisez un Réflecteur pour examiner les IL qui est généré pour chaque constructeur, vous verrez pourquoi, tu finirais par les appelant tous les constructeurs de la classe de base. En théorie, le compilateur pourrait construire caché méthodes pour accomplir ce que vous voulez, mais il n'est pas vraiment un avantage par rapport à vous de faire la même chose de manière explicite.
Je re-chaîne constructeurs, ils sont appelés comme
C'est approprié, si sans paramètre constructeurs sont de plus en une sorte de valeur par défaut pour le paramètre de type int d'autre constructeur. Si les constructeurs ne sont pas liés, vous avez probablement fait quelque chose de mal avec votre type, ou peut-être que nous avons besoin de plus d'informations sur ce que vous essayez d'atteindre.
Je voudrais vous recommandons de changer votre constructeur de la chaîne d'aller de moins spécifique à la plupart des.
La création de la Barre d'objet fera alors appel à tous les 4 constructeurs. Constructeur de chaînage doit fournir des valeurs par défaut pour les plus spécifiques des constructeurs, et non pas l'inverse. Vous devriez vraiment regarder ce que vous essayez d'accomplir et assurez-vous que ce que vous faites a un sens. Curt est juste qu'il y a des raisons techniques, vous ne pouvez pas faire cela, mais il y a aussi des raisons de logique pourquoi vous ne devriez pas.
C'est la seule chose que je peux penser...
Ne pouvez-vous pas avoir la Barre constructeur qui prend un int invoquer le constructeur sans paramètre?
Pouvez-vous mettre les trucs de Bar() dans la Barre(de type int) et d'appeler Bar(int) avec Bar() avec une valeur par défaut? Puis Bar(int) peut appeler le constructeur de base.
Qui n'est pas exactement la réponse à votre question, mais en fonction de votre scénario pourrait être une solution viable.
pouvez-vous prendre le code d'initialisation de la Barre() et en faire une méthode et de l'appeler à partir de deux constructeurs, et la nouvelle constructeur appelez simplement de base(arg)?
Vous pouvez utiliser ce code:
Juste remplacer le
InitializeObject()
méthode comme dans le code ci-dessus, et de mettre tout votre code que vous souhaitez mettre en paramètres du constructeur de là. Et enfin appelerbase.InitializeObject()
à la fin du code.Espère que cela est utile.
readonly
champs, unInitializeObject
méthode ne sera pas en mesure de le faire directement. Pour initialiser ces champs au sein d'unInitializeObject
méthode, on doit avoir le constructeur passer commeref
ouout
paramètres (j'avais faveurref
, puisque les valeurs de champ sont définies de façon à être vides lorsqu'un objet est construit, et depuis je n'aime pasout
paramètres sur les méthodes virtuelles depuis des remplacements dans d'autres langues peut les considérer commeref
paramètres).private readonly string _ro1 = "read only 1"; private readonly string _ro2; private readonly int _ro3; public Bar() : base() { } public bar(int arg) : base(arg) { _ro3 = arg; _ro2 = "read only : " + arg; }
bref, si la valeur des champs en lecture seule est déterminé par l'argument du constructeur, vous pouvez mettre sur le champ de l'initialisation sur la constuctor. Et si non, vous pouvez mettre l'initialisation tout comme le premier champ en lecture seule au-dessus (_ro1).ref
ouout
paramètres de la méthode en question. BTW, une chose que j'aimerais voir dans vb.net et C# serait un moyen de définition d'un champ ou d'un pseudo-champ qui serait initialisé avec la valeur dans un paramètre de constructeur et pourrait être utilisé plus tard dans le domaine des initialiseurs. Quelque chose comme: ...class Thing {int ArrSize = (int Size); int[] MyData = new int[ArrSize]; Thing(int Size) {};}
où la(int Size)
de l'initialisation de l'ArrSize
de croire que le constructeur de ce type, à uneint
paramètre appeléSize
ou une chaîne à celui qui n'en a, et la valeur transmise à ce paramètre doit être utilisé pour initialiserArrSize
. À mon avis, si un champ est défini une fois pour quelque chose qui peut être calculé selon les paramètres du constructeur, et jamais modifiée par la suite, il serait plus propre de combiner la déclaration et l'initialisation que de l'écrire dans les différentes places.