Différence entre la propriété et le champ dans C # 3.0+

Je me rends compte que cela semble être un doublon de Quelle est la différence entre un champ et une propriété en C #? mais ma question a une légère différence (de mon sharepoint vue):

Une fois que je sais que

  • Je ne vais pas utiliser ma classe avec “des techniques qui ne fonctionnent que sur les propriétés” et
  • Je n’utiliserai pas de code de validation dans getter / setter.

Y a-t-il une différence (sauf le style / développement futur), comme un certain type de contrôle dans la configuration de la propriété?

Y a-t-il une différence supplémentaire entre:

public ssortingng MySsortingng { get; set; } 

et

 public ssortingng mySsortingng; 

(Je suis conscient que la première version nécessite C # 3.0 ou supérieur et que le compilateur crée les champs privés.)

    Encapsulation

    Dans le second cas, vous venez de définir une variable, dans le premier, il y a un getter / setter autour de la variable. Donc, si vous décidez de valider la variable ultérieurement, cela sera beaucoup plus facile.

    De plus, ils apparaissent différemment dans Intellisense 🙂

    Edit: Mise à jour pour la question mise à jour des OP – si vous souhaitez ignorer les autres suggestions ici, l’autre raison est que ce n’est tout simplement pas une bonne conception OO. Et si vous n’avez pas une très bonne raison de le faire, choisissez toujours une propriété sur une variable / un champ public.

    Les champs et les propriétés se ressemblent, mais ils ne le sont pas. Les propriétés sont des méthodes et, en tant que telles, certaines propriétés ne sont pas sockets en charge pour les propriétés et certaines choses peuvent se produire avec les propriétés, mais jamais dans le cas des champs.

    Voici une liste de différences:

    • Les champs peuvent être utilisés comme entrée pour out/ref arguments out/ref . Propriétés ne peuvent pas.
    • Un champ donnera toujours le même résultat lorsqu’il sera appelé plusieurs fois (si nous omettons les problèmes avec plusieurs threads). Une propriété telle que DateTime.Now n’est pas toujours égale à elle-même.
    • Les propriétés peuvent générer des exceptions – les champs ne feront jamais cela.
    • Les propriétés peuvent avoir des effets secondaires ou durer très longtemps. Les champs n’ont pas d’effets secondaires et seront toujours aussi rapides que possible pour le type donné.
    • Les propriétés supportent une accessibilité différente pour les getters / setters – les champs ne le font pas (mais les champs peuvent être créés en readonly )
    • Lors de l’utilisation de la reflection, les propriétés et les champs sont traités comme des types de MemberTypes différents afin qu’ils soient situés différemment ( GetFields vs GetProperties par exemple).
    • Le compilateur JIT peut traiter l’access aux propriétés de manière très différente de l’access aux champs. Il peut cependant être compilé dans un code natif identique mais la différence est là.

    Quelques différences rapides et évidentes

    1. Une propriété peut avoir des mots-clés d’accesseur.

       public ssortingng MySsortingng { get; private set; } 
    2. Une propriété peut être remplacée dans les descendants.

       public virtual ssortingng MySsortingng { get; protected set; } 

    La différence fondamentale est qu’un champ est une position en mémoire où sont stockées les données du type spécifié. Une propriété représente une ou deux unités de code exécutées pour extraire ou définir une valeur du type spécifié. L’utilisation de ces méthodes d’access est syntaxiquement masquée en utilisant un membre qui semble se comporter comme un champ (en ce sens qu’il peut apparaître de chaque côté d’une opération d’affectation).

    Les accesseurs sont plus que des champs. D’autres ont déjà souligné plusieurs différences importantes et je vais en append une autre.

    Les propriétés participent aux classes d’interface. Par exemple:

     interface IPerson { ssortingng FirstName { get; set; } ssortingng LastName { get; set; } } 

    Cette interface peut être satisfaite de plusieurs manières. Par exemple:

     class Person: IPerson { private ssortingng _name; public ssortingng FirstName { get { return _name ?? ssortingng.Empty; } set { if (value == null) throw new System.ArgumentNullException("value"); _name = value; } } ... } 

    Dans cette implémentation, nous protégeons à la fois la classe Person contre un état invalide et l’appelant contre la nullité de la propriété non atsortingbuée.

    Mais nous pourrions pousser le design encore plus loin. Par exemple, l’interface peut ne pas traiter le setter. Il est tout à fait légitime de dire que les consommateurs d’interface IPerson ne sont intéressés que par la propriété, et non par la configuration:

     interface IPerson { ssortingng FirstName { get; } ssortingng LastName { get; } } 

    L’implémentation précédente de la classe Person satisfait cette interface. Le fait qu’elle permette à l’appelant de définir également les propriétés n’a aucun sens du sharepoint vue des consommateurs (qui consumnt IPerson ). Les fonctionnalités supplémentaires de la mise en œuvre concrète sont sockets en compte, par exemple, par le constructeur:

     class PersonBuilder: IPersonBuilder { IPerson BuildPerson(IContext context) { Person person = new Person(); person.FirstName = context.GetFirstName(); person.LastName = context.GetLastName(); return person; } } ... void Consumer(IPersonBuilder builder, IContext context) { IPerson person = builder.BuildPerson(context); Console.WriteLine("{0} {1}", person.FirstName, person.LastName); } 

    Dans ce code, le consommateur ne connaît pas les créateurs de biens – ce n’est pas son affaire de le savoir. Le consommateur n’a besoin que de passeurs, et il obtient des informations de l’interface, c’est-à-dire du contrat.

    Une autre implémentation d’ IPerson totalement valide serait une classe de personnes immuable et une fabrique de personnes correspondante:

     class Person: IPerson { public Person(ssortingng firstName, ssortingng lastName) { if (ssortingng.IsNullOrEmpty(firstName) || ssortingng.IsNullOrEmpty(lastName)) throw new System.ArgumentException(); this.FirstName = firstName; this.LastName = lastName; } public ssortingng FirstName { get; private set; } public ssortingng LastName { get; private set; } } ... class PersonFactory: IPersonFactory { public IPerson CreatePerson(ssortingng firstName, ssortingng lastName) { return new Person(firstName, lastName); } } ... void Consumer(IPersonFactory factory) { IPerson person = factory.CreatePerson("John", "Doe"); Console.WriteLine("{0} {1}", person.FirstName, person.LastName); } 

    Dans cet exemple de code, le consommateur n’a à nouveau aucune connaissance du remplissage des propriétés. Le consommateur ne s’occupe que des getters et de la mise en œuvre concrète (et de la logique métier sous-jacente, comme le test si le nom est vide) est laissé aux classes spécialisées – constructeurs et usines. Toutes ces opérations sont absolument impossibles avec les champs.

    Le premier:

     public ssortingng MySsortingng {get; set; } 

    est une propriété; le second ( public ssortingng MySsortingng ) désigne un champ.

    La différence est que certaines techniques (liaison de données ASP.NET pour les instances) ne fonctionnent que sur les propriétés et non sur les champs. La même chose est vraie pour la sérialisation XML: seules les propriétés sont sérialisées, les champs ne sont pas sérialisés.

    Les propriétés et les champs peuvent, dans de nombreux cas, sembler similaires, mais ils ne le sont pas. Il existe des limitations aux propriétés qui n’existent pas pour les champs et inversement.

    Comme d’autres l’ont mentionné. Vous pouvez créer une propriété en lecture seule ou en écriture seule en rendant son accesseur privé. Vous ne pouvez pas faire ça avec un champ. Les propriétés peuvent également être virtuelles, tandis que les champs ne le peuvent pas.

    Pensez aux propriétés comme du sucre syntaxique pour les fonctions getXXX () / setXXX (). C’est ainsi qu’ils sont mis en œuvre en coulisse.

    Il existe une autre différence importante entre les champs et les propriétés.

    Lorsque vous utilisez WPF, vous pouvez uniquement lier des propriétés publiques. La liaison à un champ public ne fonctionnera pas . Cela est vrai même si vous INotifyPropertyChanged pas INotifyPropertyChanged (même si vous en avez toujours INotifyPropertyChanged ).

    Parmi d’autres réponses et exemples, je pense que cet exemple est utile dans certaines situations.

    Par exemple, disons que vous avez une property OnChange comme suit:

     public Action OnChange { get; set; } 

    Si vous souhaitez utiliser des delegates, vous devez changer le OnChange en un field comme celui-ci:

     public event Action OnChange = delegate {}; 

    Dans une telle situation, nous protégeons notre domaine contre les access indésirables et les modifications.

    Vous devez toujours utiliser les propriétés au lieu des champs pour tous les champs publics. Cela garantit que votre bibliothèque a la possibilité d’implémenter l’encapsulation pour n’importe quel champ si nécessaire à l’avenir sans casser les codes existants. Si vous remplacez les champs par des propriétés Les modules dépendants utilisant votre bibliothèque doivent également être reconstruits.