2009-12-24 4 views
6

Je pense qu'il était en .net 2.0, Microsoft a introduit un accesseur qui a été abrégé à quelque chose commeaccesseur public .net

public string Name { get; set; }

Mais est-il une réelle différence entre le code ci-dessus, et simplement:

public string Name; 
+1

Vous pourriez vouloir lire ceci: http://stackoverflow.com/questions/1019571/why-do-we-use-net-properties-instead-of-plain-old-get-set-set-functions –

+1

http: //stackoverflow.com/questions/1272521/propertywith-no-extra-processing-vs-public-field – Groo

+1

c'est la fonction AC# 3.0 (.NET 3.5) pour être exact –

Répondre

6

La principale différence est que si vous avez besoin plus tard pour ajouter une logique dans votre getter ou setter, et d'autres DLL ont déjà été compilés contre le vôtre, vous pouvez facilement changer

public string Name { get; set; } 

dans

public string Name { get{/*special code*/} set{/*special code*/} } 

et il ne sera pas un changement de rupture pour publier votre nouvelle DLL et d'autres DLL ne seront pas recompilées.


Alors que si vous avez changé

public string Name; 

dans

public string Name { get{/*special code*/} set{/*special code*/} } 

alors vous devez vous assurer que toutes les DLL qui utilisent le vôtre sont recompilés, car ils changent d'avoir accès à un champ en accéder à une propriété.

Ceci est évidemment un plus gros problème quand vous DLLs expédition à d'autres programmeurs (comme un projet open source ou en tant que fournisseur de composants par exemple) que si vous construisez juste une application pour votre propre/employeur

+0

Intéressant, pourquoi dans le second cas le code compilé est différent. Quelle est l'intention de compiler le champ de sorte que tous les clients doivent reconstruire dès qu'un champ est remplacé par une propriété. –

+0

parce que dans les MSIL, les accès aux propriétés sont un type particulier d'appel de méthode, alors qu'un accès aux champs est juste un accès aux champs. –

+2

A titre d'exemple de différence: vous pouvez utiliser un champ comme paramètre "out" ou "ref" pour une méthode, mais vous ne pouvez pas le faire avec une propriété. Donc, le code qui a utilisé le champ de cette façon se casse si vous le changez en propriété. –

4

la différence entre un Field et un Property. Un champ est juste une variable membre sur l'instance de la classe. En revanche, une propriété est un raccourci pour deux actions distinctes - obtenir et définir:

public string Name 
{ 
    get 
    { 
     return _name; 
    } 
    set 
    { 
     _name = value; 
    } 
} 

private string _name; 

Ceci est un simpliste exemple, comme la propriété simplement « enveloppe » le champ privé en retournant dans le getter et le mettre dans le setter. Cependant, les propriétés deviennent très utiles lorsqu'elles deviennent des «passerelles» vers la valeur sous-jacente. Si le déroulement du programme exige quelque chose se produit chaque fois que la valeur d'un champ est défini (par exemple, un événement est déclenché), il peut être tiré du setter de la propriété:

set 
{ 
    this.InvokePropertyChangedEvent(); 
    _name = value; 
} 

La syntaxe exacte que vous vous posez au sujet est appelé Auto-Implemented Properties, qui est juste un raccourci pour l'exemple simple que j'ai fourni ci-dessus. Le compilateur crée un membre privé obtenu et défini par la propriété.

+1

@Rex: Mais ce n'est pas ce qui a été demandé en question. La question concerne la différence entre les déclarations et non la différence entre un champ et une propriété. –

+0

@curious une explication complète de la différence entre les deux déclarations nécessite des informations de base que nous ne pouvons pas supposer que l'OP a déjà. Le peu que vous cherchez est à la fin. –

+0

Je voulais écrire sur l'élever des événements dans ma réponse, mais encore une fois ce n'est pas la question. –

4

Les propriétés automatiques ont d'abord été introduites dans C# 3.0. La différence entre:

public string Name { get; set; } 

et

public string Name; 

est que le premier déclare un property tandis que le second une field. Dans les propriétés OOP sont utilisées pour encapsuler des champs. Une propriété peut avoir un setter ou un getter ou les deux et vous pouvez également spécifier un niveau d'accessibilité différent pour chacun.

1

Oui, le code dans la deuxième ligne vous rend disponible directement le membre en mémoire alors que dans la première ligne vous avez un niveau d'indirection où vous pouvez ajouter une logique dans le futur pour valider et assigner paresseux. De plus, si vous utilisez un reflet, vous devrez rechercher le Property Setter et Getter pour le premier exemple de ligne et pour le second, vous devrez récupérer directement une variable membre.

Habituellement, l'utilisation de Properties est une conception bien meilleure.

2

La différence entre la déclaration de propriété abrégée est que vous pouvez la définir de cette façon. Cela signifie que cette propriété peut être lue publiquement mais que seuls les membres privés peuvent y écrire. Vous ne pouvez pas faire une telle chose pour un champ.

Si vous regardez l'IL généré des déclarations de propriété sténographie, vous trouverez que le compilateur a ajouté /membres des champs autogénérées à une propriété va lire ou écrire dans.

+0

La possibilité d'ajouter accesseur modifyier rend sence. Utilise un accès différent dans un getter et un setter plusieurs fois mais pas dans une déclaration sténographique. Je me demandais à propos de cette question aussi, mais je ne pouvais pas prendre la peine de demander. Maintenant, c'est plus clair. Bien que je ne serai pas surpris s'il y a d'autres différences. –

2

Il n'y a pas de différence fonctionnelle en ce qui concerne l'écriture de code pour obtenir la valeur ou la stocker. Mais il y a des cas où un appelant pourrait s'attendre à un champ ou à une propriété et n'accepterait que l'un ou l'autre en utilisant la réflexion. Par exemple, WPF peut uniquement se lier à une propriété et non à un champ.

0

Une différence utile que j'ai trouvée pour les utilisateurs de propertygrid est que: public string Name {get; ensemble; } nous pourrions définir les données source dans Propertygrid facilement. Lors de la déclaration chaîne publique Nom; ne sera pas utilisé pour Propertygrid.

Questions connexes