Pourquoi est primordial méthode statique admis en C#
protected static new void WhyIsThisValidCode()
{
}
Pourquoi êtes-vous autorisé à remplacer les méthodes statiques?
Rien mais les bugs ne peut venir de lui, il doensn fonctionne pas comme on pourrait le croire.
Prendre les classes suivantes.
class BaseLogger
{
protected static string LogName { get { return null; } }
public static void Log(string message) { Logger.Log(message, LogName); }
}
class SpecificLogger : BaseLogger
{
protected static string LogName { get { return "Specific"; } }
}
c'est admis, et le code
SpecificLogger.Log("test");
est altso admis, mais il ne fait pas ce qu'on pourrait penser en regardant le code.
il appelle Logger.Log
avec LogName = null
.
Alors pourquoi est-ce autorisé?
Comme d'autres l'ont dit, ce n'est pas primordial et il ne exactement comme je l'avais prévu. S'il vous plaît ne présumez pas que tout le monde pense de la même façon que vous.
OriginalL'auteur AndreasN | 2010-11-16
Vous devez vous connecter pour publier un commentaire.
La
new
mot-clé ne remplace pas une méthode. Au lieu de cela, il crée une nouvelle méthode du même nom, qui est indépendante de l'original. Il n'est pas possible de surcharger une méthode statique parce qu'ils ne sont pas virtuelsOriginalL'auteur JaredPar
Vous n'êtes pas primordial, vous êtes en cacher. Une méthode normale serait présentent exactement le même comportement, donc il n'y a rien de spécifique à des méthodes statiques ici.
Cacher n'est utile que dans quelques cas. Celui où je suis tombé sur le plus souvent c'est de faire le type de retour plus spécifiques dans une classe dérivée. Mais je n'ai jamais eu qui se produisent avec des méthodes statiques.
Un domaine où les fonctions statiques avec un certain nom pourrait être utile si vous utilisez la réflexion et souhaitez obtenir des informations sur chaque classe en la retournant à partir d'une méthode. Mais bien sûr, dans la plupart des cas, un attribut correspond le mieux.
Et il n'est pas susceptible de créer des bugs depuis votre code produit par le compilateur avertissement:
Et si vous utilisez
new
vous devez savoir ce que vous faites.OriginalL'auteur CodesInChaos
D'autres ont fait remarquer que ce n'est pas primordial, mais cela laisse quand même à votre question de départ: pourquoi êtes-vous en mesure de le faire? (Mais la question est "pourquoi ne pouvez-vous cacher méthodes statiques".)
C'est une conséquence inévitable de soutenir les indépendants, la gestion des versions des composants qui contiennent des classes de base et des composants que l'utilisation de ces classes de base.
Par exemple, imaginez que composant CompB contient la classe de base, et d'autres composants CompD contient une classe dérivée. Dans la version 1 de CompB, il ne peut pas y avoir de propriété appelée LogName. L'auteur de CompD décide d'ajouter une propriété statique appelé LogName.
La chose essentielle à comprendre à ce point, c'est que l'auteur de la v1 de CompD n'avais pas l'intention de remplacer ou de masquer toute fonction de la classe de base - il n'y a aucun membre appelé LogName dans la classe de base quand ils ont écrit le code.
Imaginez maintenant qu'une nouvelle version de la CompB bibliothèque est libéré. Dans cette nouvelle version, l'auteur a ajouté un LogName de la propriété. Ce qui est censé se produire dans CompD? Les options semblent être les suivants:
.NET choisit de le faire 3. (Et il le fait avec à la fois les aspects statiques et non statiques. Si vous voulez comportement 2 - remplacement - avec les non-statique, puis la base doit être
virtual
et la classe dérivée a marquer la méthodeoverride
de préciser qu'ils ont été délibérément remplacement d'une méthode dans la classe de base. C# ne fera jamais d'une classe dérivée de la méthode de remplacer une classe de base de la méthode, sauf si la classe dérivée a déclaré explicitement que c'est ce qu'ils voulaient.) Cela est susceptible d'être en sécurité parce que les deux membres ne sont pas liés - la base LogName n'existait même pas au point où la dérivée de l'un a été introduit. Et c'est préférable de simplement casser parce que la dernière version de la classe de base introduit un nouveau membre.Sans cette fonctionnalité, il serait impossible pour les nouvelles versions de la .NET Framework pour ajouter de nouveaux membres existants des classes de base sans que cela soit d'une modification de rupture.
Vous dire que le comportement n'est pas ce que vous attendez. En fait, c'est exactement ce à quoi je m'attend, et ce que vous voudrez probablement dans la pratique. Le BaseLogger n'a aucune idée que le SpecificLogger a introduit ses propres LogName de la propriété. (Il n'y a pas de mécanisme par lequel il pourrait parce que vous ne pouvez pas remplacer les méthodes statiques.) Et lorsque l'auteur de SpecificLogger écrit que LogName de la propriété, n'oubliez pas qu'ils ont été écrit en fonction de v1 de BaseLogger qui n'ont pas un LogName, de sorte qu'ils n'avaient pas l'intention qu'il doit remplacer la méthode de base. Étant donné que ni la classe veut remplacement, clairement remplacement serait une mauvaise chose.
Le seul scénario dans lequel vous devriez vous retrouver dans cette situation est le fait que les deux classes de composants différents. (Bien entendu, on peut imaginer un scénario quand ils sont dans la même composante, mais pourquoi voudriez-vous faire cela? Si vous possédez les deux morceaux de code et de les libérer dans un seul composant, il faudrait être fou jamais de le faire.) Et donc BaseLogger devrait obtenir sa propre LogName de la propriété, ce qui est exactement ce qui se passe. Vous pouvez avoir écrit:
mais le compilateur C# voit que SpecificLogger ne fournit pas une méthode Journal, de sorte qu'il se transforme en:
parce que c'est là le Journal méthode est définie.
Donc, chaque fois que vous définissez une méthode dans une classe dérivée qui n'est pas de tenter de substituer une méthode existante, le compilateur C# indique ce dans les métadonnées. (Il y a un "newslot" paramètre dans la méthode de métadonnées qui dit, cette méthode est destinée à être flambant neuf, rien à voir avec quoi que ce soit dans la classe de base.)
Mais cela vous donne un problème si vous voulez recompiler CompD. Disons que vous avez un rapport de bug en raison de certains tout à fait sans rapport avec les bits de code et vous avez besoin de sortir une nouvelle version de CompD. Vous le compiler à l'encontre de la nouvelle verison de CompB. Si le code que vous avez écrit n'était pas autorisé, vous ne pouvez pas être en mesure de les vieux de code déjà compilé, mais vous ne pouvez pas être en mesure de compiler de nouvelles versions de ce code, ce qui serait un peu fou.
Et donc, à l'appui de cette (franchement un peu obscure) scénario, ils vous permettent de faire cela. Ils génèrent un avertissement pour vous laisser savoir que vous avez une appellation s'affrontent ici. Vous devez fournir les
new
mot-clé pour se débarrasser de lui.C'est un obscur scénario, mais si vous voulez soutenir héritage de l'autre côté de la composante limites, vous avez besoin de ce, sinon l'ajout de nouveaux publics ou protégés, les membres de la classe de base serait invariablement une modification de rupture. C'est pourquoi c'est ici. Mais c'est une mauvaise pratique jamais compter sur elle, d'où le fait que vous obtenez un avertissement du compilateur. L'utilisation de la
new
mot-clé pour se débarrasser de l'avertissement ne doit jamais être un pis-aller.La ligne de fond est: est-ce que cette fonctionnalité existe pour une seule raison, et c'est à vous sortir d'un trou dans les situations où une nouvelle version de certains de la classe de base a ajouté un membre qui n'existait pas encore, et qui soit en conflit avec un membre qui est déjà sur votre classe dérivée. Si ce n'est pas la situation où vous êtes, ne pas utiliser cette fonction.
(Je pense qu'ils devraient émettre une erreur plutôt que d'un avertissement lorsque vous quitter de nouveaux, afin de rendre cela plus clair.)
OriginalL'auteur Ian Griffiths
Méthodes statiques et les champs n'appartiennent pas à des instances de classe, mais à des définitions de classe. Les méthodes statiques ne jouent pas de rôle dans le virtuel mécanisme de distribution et ne font pas partie de la table de méthode virtuelle.
Ils sont tout simplement des méthodes et des champs spécifiques de la classe.
Il peut regarder comme les méthodes et les champs sont "héritées" parce que vous pouvez faire
SpecificLogger.Log()
, mais c'est juste quelque chose pour vous éviter d'avoir à en référer à la classe de base de tous les temps.Méthodes statiques et les champs sont vraiment juste de méthodes globales et les champs, à l'OO genre.
OriginalL'auteur Pieter van Ginkel
Vous n'êtes pas en remplaçant la propriété dans la classe de base, mais au lieu de le cacher. La propriété réelle utilisé lors de l'exécution dépend de ce que l'interface vous travaillez contre. L'exemple suivant l'illustre:
Dans votre code de la méthode Log est en fait à l'encontre de la BaseLogger interface - parce que le Journal méthode fait partie de la BaseLogger classe.
Méthodes et propriétés statiques ne peuvent pas être remplacés, et quand vous voulez cacher une propriété, vous devez utiliser le
new
mot-clé pour indiquer que vous cachez quelque chose.OriginalL'auteur Simon Bartlett
pour ma surprise de code suivant est autorisé et compile sans erreur .net Framework 4.5.1, VS 2013.
OriginalL'auteur Paras