C # 3.0 Propriétés automatiques, pourquoi ne pas accéder directement au champ?

StackOverflow https://stackoverflow.com/questions/174198

  •  05-07-2019
  •  | 
  •  

Question

Avec la nouvelle approche consistant à avoir le get / set dans l'attribut de la classe, comme ceci:

public string FirstName {
        get; set;
    }

Pourquoi simplement ne pas simplement mettre l'attribut FirstName public sans accesseur?

Était-ce utile?

La solution

Deux des gros problèmes avec l'accès direct à la variable à l'intérieur de la classe (champ / attribut) sont:

1) Vous ne pouvez pas facilement retrouver des données dans des champs.

2) Si vous exposez des champs publics de vos classes, vous ne pourrez plus les modifier en propriétés (par exemple, pour ajouter une logique de validation aux paramètres)

Autres conseils

Parce que, à l'avenir, si vous modifiez l'implémentation, le code utilisant l'interface actuelle ne sera pas interrompu.

Par exemple, vous implémentez une classe simple avec un champ public et commencez à utiliser votre classe dans certains modules externes. Un mois plus tard, vous découvrez que vous devez implémenter le chargement différé dans cette classe. Vous devrez ensuite transformer le champ en propriété. Du point de vue du module externe, cela pourrait ressembler à la même syntaxe, mais ce n’est pas le cas. Une propriété est un ensemble de fonctions, tandis qu'un champ est un décalage dans une instance de classe.

En utilisant une propriété, vous réduisez efficacement le risque de modification de l'interface.

Cela revient principalement au fait qu’il soit devenu une convention de codage commune. Il est alors facile d’ajouter du code de traitement personnalisé si vous le souhaitez. Mais vous avez raison, il n’est techniquement pas nécessaire de le faire. Toutefois, si vous ajoutez un traitement personnalisé ultérieurement, cela vous aidera à ne pas endommager l'interface.

Ce style de notation est plus utile lorsque vous mélangez l’accessibilité pour le getter et le setter. Par exemple, vous pouvez écrire:

public int Foo { get; private set; }

Vous pouvez également mettre un setter interne, ou même rendre le getter privé et le setter public.

Cette notation évite d'avoir à écrire explicitement une variable privée uniquement pour traiter le problème classique de la valeur inscriptible / lisible en interne.

La clé est que le compilateur traduit la propriété 'sous le capot' en une paire de fonctions. Lorsque vous avez du code qui ressemble à utiliser la propriété, il appelle en fait des fonctions lorsqu'il est compilé en IL.

Supposons donc que vous construisez ceci en tant que champ et que le code soit dans un assemblage séparé qui utilise ce champ. Si, par la suite, l'implémentation change et que vous décidez d'en faire une propriété pour masquer les modifications du reste de votre code, vous devez toujours recompiler et redéployer l'autre assemblage. Si c'est une propriété dès le départ, tout ira bien.

Je pense que le questionneur demande pourquoi ne pas procéder comme suit ...

public string FirstName { }

Pourquoi s'embêter avec les accesseurs quand vous pouvez le raccourcir à ce qui précède. Je pense que la réponse est qu’en exigeant les accesseurs, il est évident pour la personne qui lit le code qu’il s’agit d’un get / set standard. Sans eux, vous pouvez voir ci-dessus qu'il est difficile de savoir si cela est automatiquement mis en œuvre.

Lorsque vous rencontrez un bogue et que vous devez savoir quelles méthodes modifient vos champs et à quel moment, vous vous en soucierez beaucoup plus. Le fait de mettre des accesseurs de propriétés légers à l’avant permet d’économiser une quantité phénoménale de chagrin d’âme si un bogue survient concernant le champ que vous avez enveloppé. Cela fait plusieurs fois que je suis dans cette situation et ce n’est pas agréable, surtout s’il s’avère lié à la rentrée.

Faire ce travail en amont et coller un point d'arrêt sur un accesseur est beaucoup plus facile que les alternatives.

Dans 99% des cas, exposer un champ public est acceptable.

Le conseil commun est d'utiliser des champs: "Si vous exposez des champs publics de vos classes, vous ne pourrez plus les changer en propriétés". Je sais que nous voulons tous que notre code soit à l'épreuve du temps, mais cette réflexion présente certains problèmes:

  • Les consommateurs de votre classe peuvent probablement recompiler lorsque vous modifiez votre interface.

  • 99% des membres de vos données n'auront jamais besoin de devenir des propriétés non triviales. Il s'agit de la généralité spéculative . Vous écrivez beaucoup de code qui ne sera probablement jamais utile.

  • Si vous avez besoin d'une compatibilité binaire entre les versions, il ne suffit probablement pas de rendre les membres de données dans des propriétés. À tout le moins, vous ne devez exposer que des interfaces, masquer tous les constructeurs et exposer les usines (voir le code ci-dessous).

public class MyClass : IMyClass
{
    public static IMyClass New(...)
    {
        return new MyClass(...);
    }
}

C’est un problème difficile, nous essayons de créer un code qui fonctionnera dans un avenir incertain. Vraiment difficile.

Quelqu'un a-t-il un exemple d'une époque où l'utilisation de propriétés triviales sauvait son bacon ?

Conserve l'encapsulation de l'objet et réduit le code pour qu'il soit plus simple à lire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top