Javaer résume comment écrire des propriétés C #

introduction

Le premier langage de programmation que j'ai appris était Java, mais je ne comprenais pas vraiment le concept et l'écriture des propriétés C #, alors j'aimerais l'organiser.

Qui est la cible de cet article

Comparaison du style d'écriture

supposition

Considérez la ** classe humaine **, qui est courante dans les explications orientées objet. Supposons que la classe Human possède les champs et la visibilité suivants:

--nickname …… Vous pouvez facilement changer le surnom. Il n'y a aucune restriction et vous pouvez librement récupérer et réécrire. --realname …… Le vrai nom ne peut pas être changé aussi facilement. Je peux donc le supprimer, mais je ne peux pas le réécrire. ――Age …… L'âge peut lire le maquereau, donc cette fois je vais le réécrire. Cependant, comme il s'agit d'un âge, il doit être âgé d'au moins 0 ans.

Pour atteindre cette exigence, la classe doit ressembler à ceci:

--nickname: j'ai à la fois getter / setter. --realname: n'a qu'un getter. --age: j'ai un getter et un setter conditionnel.

De plus, cette fois, nous définirons également un constructeur qui peut définir ce champ en même temps que l'instanciation.

Java Dans le cas de Java, il y a beaucoup d'écriture, mais c'est simple à faire. Les champs qui devraient être honnêtement définis sont définis comme des variables privées, et getter / setter sont définis comme des méthodes publiques. Si vous voulez mettre une limite, écrivez la logique dans la méthode. Si vous ne voulez pas être accédé en premier lieu, tout ce que vous avez à faire est d'écrire une méthode. Le constructeur prend également les arguments dans l'ordre et les définit dans ses propres champs.

public class Main {
    public static void main(String[] args) throws Exception {
        Human konan = new Human("Shinichi Kudo", "Mais, Kudo", 17);

        //Vous pouvez récupérer librement votre pseudo, votre vrai nom et votre âge.
        System.out.println(konan.getNickname()); // ->Mais, Kudo
        System.out.println(konan.getRealname()); // ->Shinichi Kudo
        System.out.println(konan.getAge()); // -> 17
        
        //Le pseudo et l'âge peuvent être réécrits
        konan.setNickname("Conan Edogawa");
        konan.setAge(7);
        System.out.println(konan.getNickname()); // ->Conan Edogawa
        System.out.println(konan.getAge()); // -> 7
        
        //Cependant, même si vous entrez dans un âge étrange, il sera ignoré
        konan.setAge(-10000);
        System.out.println(konan.getAge()); // ->Reste 7
        
        //Vous ne pouvez pas changer votre vrai nom.
        // konan.setRealname("Conan Edogawa"); // ->Je me fâche parce qu'il n'y a pas de telle méthode.
        
        //Alors Conan, quel est ton vrai nom?
        System.out.println(konan.getRealname()); // ->Shinichi Kudo. Ah ... après tout.
    }
}

class Human{
    private String realname;
    private String nickname;
    private int age;
    
    public Human(String realname, String nickname, int age){
        this.realname = realname;
        this.nickname = nickname;
        if (age >= 0){
            this.age = age;
        }
    }
    
    public String getRealname(){
        return realname;
    }
    
    public String getNickname(){
        return nickname;
    }
    
    public void setNickname(String nickname){
        this.nickname = nickname;
    }
    
    public int getAge(){
        return age;
    }
    
    public void setAge(int age){
        if (age >= 0){
            this.age = age;
        }
    }
}

Il y a beaucoup de code dans la classe Human. Cette fois, j'ai fixé des conditions et des restrictions, donc je ne me sens pas si désagréable, mais si pratiquement tous les champs sont accessibles et des cours à volonté, je me sens stérile. Dans certains cas, la bibliothèque appelée Lombok peut être écrite un peu plus propre, et dans d'autres cas, la méthode getter / setter est automatiquement générée en utilisant la fonction de l'EDI, mais elle est transmise à une autre personne.

Par conséquent, il semble que les langues modernes implémentent souvent une manière spéciale d'écrire leurs propres champs (bien qu'ils soient également appelés attributs) getter / setter. C # en fait partie.

C# En C #, une fonction appelée properties est utilisée pour réécrire et récupérer des champs de l'extérieur. Il semble que vous réécrivez directement le champ. Cependant, comme c'est en fait via quelque chose comme une méthode getter / setter, cela est écrit en ** cas Pascal ** (en C #, le nom de la méthode est le cas Pascal). Lorsque vous utilisez des propriétés, vous n'avez pas l'impression de passer par une méthode à chaque fois, et vous avez l'impression d'attribuer ou de référencer directement.

using System;

public class Program
{
    public static void Main()
    {
        Human konan = new Human("Shinichi Kudo","Mais, Kudo",17);
        
        //Vous pouvez récupérer librement votre pseudo, votre vrai nom et votre âge.
        Console.WriteLine(konan.Nickname); // ->Mais, Kudo
        Console.WriteLine(konan.Realname); // ->Shinichi Kudo
        Console.WriteLine(konan.Age); // -> 17
        
        //Le surnom et l'âge peuvent être réécrits.
        konan.Nickname = "Conan Edogawa";
        konan.Age = 7;
        Console.WriteLine(konan.Nickname); // ->Conan Edogawa
        Console.WriteLine(konan.Age); // ->7
        
        //Cependant, même si vous entrez dans un âge étrange, il sera ignoré
        konan.Age = -10000;
        Console.WriteLine(konan.Age); // ->Reste 7

        //Tu ne peux pas changer ton vrai nom
        // konan.Realname = "Conan Edogawa"; //Sa propriété est Read-Mettez-vous en colère contre Only
        
        //Alors Conan, quel est ton vrai nom?
        Console.WriteLine(konan.Realname); // ->Shinichi Kudo. Ah ... après tout.
    }
}

class Human
{
    public string Realname{ get; }
    public string Nickname{ get; set; }
    private int age;
    public int Age
    {
        get
        {
            return this.age;
        }
        set{
            if (value >= 0)
            { 
                this.age = value;
            }
        }
    }
    
    public Human(string realname, string nickname, int age)
    {
        this.Realname = realname;
        this.Nickname = nickname;
        if (age >= 0)
        {
            this.Age = age;
        }
    }
}

Si vous voulez utiliser une propriété qui peut être lue ou écrite, écrivez simplement {get; set;} après le nom de la propriété. Si vous souhaitez utiliser la propriété en lecture seule, utilisez {get;} [^ 1]. Si vous souhaitez retourner ou définir après avoir effectué un traitement en interne lors de la définition ou de l'obtention, préparez un champ séparé (il s'agit d'une variable normale, donc le cas de camel) et après la déclaration de propriété Écrivez comme suit.

[^ 1]: ~~ En fait, la propriété en écriture seule ne semble pas être prise en charge en C #. Dans ce cas, il sera implémenté séparément en tant que méthode de pose normale. ~~ En utilisant private get, vous pouvez utiliser des propriétés en écriture seule (voir postscript).

{
    get
    {
        //Quelque chose de traitement
retour Résultat traité;
    }
    set
    {
        //Quelque chose traité en utilisant la valeur
        this.champ=Résultat du traitement;
    }
}

A ce moment, à l'intérieur du setter, la valeur reçue est automatiquement reçue avec l'argument nommé «value».

Cette fois, certaines propriétés sont en lecture seule, donc le constructeur ressemble à Java, mais si toutes les propriétés ont l'autorisation d'écriture, vous n'avez pas à préparer un constructeur. Vous pouvez écrire quelque chose comme ceci: C'est très propre.

Human konan = new Human(){ Realname = "Shinichi Kudo", Nickname = "Mais, Kudo", Age = 17 };

en conclusion

Il y a beaucoup de discussions sur les avantages et les inconvénients du getter / setter, mais c'est toujours inévitable quand on parle d'encapsulation orientée objet. Depuis que je viens de Java, je comprends que les objets n'ont que des variables et des méthodes. Même si c'était facile à comprendre, j'avais l'impression que c'était redondant et gênant.

Quand j'ai vu le code C # pour la première fois, je ne connaissais même pas la fonction des propriétés, alors pourquoi ce gars écrit-il des variables dans le cas Pascal? J'ai pensé, mais quand je l'ai recherché, j'ai été impressionné par le fait qu'il puisse être écrit de manière aussi concise. Cependant, d'un autre côté, si la logique est incluse dans getter / setter, elle sera légèrement retardée et ce sera difficile à voir, et puisque le style d'écriture autour de cela évolue avec chaque mise à niveau de version de C #, tout en étudiant J'ai eu l'impression que c'était assez déroutant parce que beaucoup d'informations telles que «Je peux écrire comme ça» et «J'écrivais comme ça» sont sorties et j'étais confuse.

Cet article est également un résumé pour moi. Nous espérons que cet article vous a aidé à améliorer votre vie C #.

Postscript (2019/3/29)

Valeur par défaut

Comme j'ai oublié de l'écrire dans l'article ci-dessus, vous pouvez donner des valeurs initiales aux propriétés C #. Par exemple, si vous souhaitez donner à un objet Humain nouveau-né le nom "anonyme", vous pouvez écrire:

string name{ get; set; } = "Anonyme";

Cela seul est bien, mais c'est utile lorsque vous voulez avoir un objet d'une classe comme propriété dans la classe, par exemple.

class Human{
    public List<string> Tools{ get; set; } = new List<string>();
}

De cette façon, vous pouvez manipuler cette propriété soudainement depuis l'extérieur des objets de cette classe.

var konan = new Human();
konan.Tools.Add("Changeur de voix de type nœud papillon");
konan.Tools.Add("Chaussures d'amélioration de la puissance de coup de pied");
konan.Tools.Add("Pistolet d'anesthésie de type montre"); 

Si vous essayez de le faire sans initialiser les propriétés, vous obtiendrez une NullReferenceException. Pour éviter cela, vous devez faire de nouveaux en dehors de la classe, puis vous y tenir.

(Thx: C # er de la même société)

propriété en écriture seule

Dans le premier article, j'ai écrit que la propriété en écriture seule ne peut pas être utilisée, mais en réalité, il semble qu'elle puisse être utilisée en en faisant une propriété private get. Vous ne pourrez pas lire vos propriétés même à l'intérieur.

Donc,

public string Secret { set; }

Ne peut pas être écrit, mais

public string Secret { private get; set; }

Peut être écrit comme.

var konan = new Human();
konan.Secret = "En fait, Shinichi";
// Console.WriteLine(konan.Secret); ←Write-Mettez-vous en colère contre Only

(Merci: @muniel)

type uint

Cette fois, je l'ai écrit en supposant que certains traitements seront effectués au setter, j'ai donc utilisé le type int, mais il semble y avoir un type appelé type uint (Unsigned Int) appelé entier non signé. Le type int gère -2147483648 à 2147483647, tandis que le type uint gère 0 à 4294967295.

Cependant, comme le type uint ne peut fondamentalement pas gérer les nombres négatifs, par exemple, «10-20» ne devient pas «-10», mais «4294967286» (en raison de l'opération sur les bits, il se retourne et se précipite dans le plus grand). Cela peut être un foyer de bogues en raison d'un comportement inattendu. Fondamentalement, il semble que le type uint ne doit pas être utilisé pour la valeur qui peut être la cible de l'arithmétique.

Cependant, si vous voulez vraiment créer un objet humain, définir l'âge sur une propriété set / getable mettra à jour l'âge chaque année, vous avez donc probablement un anniversaire en tant que propriété à l'intérieur, et l'âge est basé sur cela. Il semble bon d'en faire une propriété en lecture seule qui calcule et renvoie une valeur. (Merci: @ Tonbo0710, @ tak458, @ Zuishin)

Vous pouvez également utiliser setter dans le constructeur

public Human(string realname, string nickname, int age)
{
    this.Realname = realname;
    this.Nickname = nickname;
    if (age >= 0)
    {
        this.Age = age;
    }
}

Dans l'article ci-dessus, l'instruction if est utilisée pour empêcher l'insertion de valeurs étranges même dans le constructeur, mais si vous y réfléchissez attentivement, vous définissez ici la valeur via votre propre propriété, et dans ce setter Puisqu'il est jugé par, cela doit être écrit comme suit [^ 2]. De plus, la propriété et le nom de la variable reçue ne sont pas en conflit dans le cas Pascal et le cas camel, donc «this» peut être présent ou non.

public Human(string realname, string nickname, int age)
{
    this.Realname = realname;
    this.Nickname = nickname;
    this.Age = age;
}

(Thx: Yamada)

[^ 2]: Il semble que vous ne pouvez définir de l'extérieur que dans le constructeur sans écrire private set.

Recommended Posts

Javaer résume comment écrire des propriétés C #
[Java FX] Comment écrire des autorisations Eclipse dans build.gradle
JUnit 5: Comment écrire des cas de test dans enum
Comment écrire Java String # getBytes dans Kotlin?
Notes sur la façon de rédiger des commentaires en anglais
Comment écrire des rails
Comment écrire docker-compose
Comment écrire Mockito
Comment écrire un fichier de migration
[Ruby on Rails] Comment écrire enum en japonais
Comment écrire une recherche de comparaison de dates dans Rails
Comment écrire un mod de base dans Minecraft Forge 1.15.2
Comment écrire un exemple d'implémentation du problème dans E05 (ruby, C11) en temps réel hors ligne
Comment écrire du bon code
Comment rédiger un commentaire java
[Refactoring] Comment écrire le routage
Comment écrire Junit 5 organisé
Comment écrire des graines de Rails
Comment écrire le routage Rails
[Rails 5] lien japanMap Comment écrire des paramètres dans le fichier js.erb
[Rails] Comment écrire user_id (clé externe) dans un paramètre fort
Comment utiliser Lombok au printemps
Comment trouver May'n dans XPath
Comment masquer la barre de défilement dans WebView
Comment exécuter JUnit dans Eclipse
Comment itérer indéfiniment en Ruby
Étudier Java # 6 (Comment écrire des blocs)
Lire le fichier de propriétés Java en C #
Comment exécuter Ant dans Gradle
Comment maîtriser la programmation en 3 mois
Comment apprendre JAVA en 7 jours
Comment obtenir des paramètres dans Spark
Comment écrire un exemple d'implémentation F03 ruby et C en temps réel hors ligne
Comment installer Bootstrap dans Ruby
Comment écrire Ruby en une seule ligne Résumé par débutant
Comment écrire lorsque vous voulez gérer un "tableau de chaînes en langage C" comme argv [] dans Ruby-FFI
Comment utiliser InjectorHolder dans OpenAM
[Rails] Comment écrire la gestion des exceptions?
Comment écrire une déclaration de variable Java
Comment installer jQuery dans Rails 6
Comment utiliser les classes en Java?
Comment nommer des variables en Java
Comment définir Lombok dans Eclipse
Comment rédiger un code facile à comprendre [Résumé 3]
Comment concaténer des chaînes avec Java
Comment installer Swiper in Rails
[swift5] Comment spécifier la couleur en hexadécimal