diff options
-rw-r--r-- | csharp.html.markdown | 8 | ||||
-rw-r--r-- | css.html.markdown | 11 | ||||
-rw-r--r-- | fr-fr/csharp-fr.html.markdown | 812 | ||||
-rw-r--r-- | zh-cn/clojure-macro-cn.html.markdown | 151 | ||||
-rw-r--r-- | zh-cn/visualbasic-cn.html.markdown | 274 |
5 files changed, 1247 insertions, 9 deletions
diff --git a/csharp.html.markdown b/csharp.html.markdown index 81b50e08..a689fe97 100644 --- a/csharp.html.markdown +++ b/csharp.html.markdown @@ -435,7 +435,7 @@ on a new line! ""Wow!"", the masses cried"; Func<int, int> square = (x) => x * x; // Last T item is the return value Console.WriteLine(square(3)); // 9 - // DISPOSABLE RESSOURCES MANAGEMENT - let you handle unmanaged resources easily. + // DISPOSABLE RESOURCES MANAGEMENT - let you handle unmanaged resources easily. // Most of objects that access unmanaged resources (file handle, device contexts, etc.) // implement the IDisposable interface. The using statement takes care of // cleaning those IDisposable objects for you. @@ -511,11 +511,11 @@ on a new line! ""Wow!"", the masses cried"; var db = new BikeRespository(); // execution is delayed, which is great when querying a database - var fitler = db.Bikes.Where(b => b.HasTassles); // no query run + var filter = db.Bikes.Where(b => b.HasTassles); // no query run if (42 > 6) // You can keep adding filters, even conditionally - great for "advanced search" functionality - fitler = fitler.Where(b => b.IsBroken); // no query run + filter = filter.Where(b => b.IsBroken); // no query run - var query = fitler + var query = filter .OrderBy(b => b.Wheels) .ThenBy(b => b.Name) .Select(b => b.Name); // still no query run diff --git a/css.html.markdown b/css.html.markdown index 26eaae53..76319340 100644 --- a/css.html.markdown +++ b/css.html.markdown @@ -2,6 +2,7 @@ language: css contributors: - ["Mohammad Valipour", "https://github.com/mvalipour"] + - ["Marco Scannadinari", "https://github.com/marcoms"] filename: learncss.css --- @@ -129,11 +130,11 @@ selector { width: 5in; /* in inches */ /* Colors */ - background-color: #F6E /* in short hex */ - background-color: #F262E2 /* in long hex format */ - background-color: tomato /* can be a named color */ - background-color: rgb(255, 255, 255) /* in rgb */ - background-color: rgb(10%, 20%, 50%) /* in rgb percent */ + background-color: #F6E; /* in short hex */ + background-color: #F262E2; /* in long hex format */ + background-color: tomato; /* can be a named color */ + background-color: rgb(255, 255, 255); /* in rgb */ + background-color: rgb(10%, 20%, 50%); /* in rgb percent */ background-color: rgba(255, 0, 0, 0.3); /* in semi-transparent rgb */ /* Images */ diff --git a/fr-fr/csharp-fr.html.markdown b/fr-fr/csharp-fr.html.markdown new file mode 100644 index 00000000..c1641716 --- /dev/null +++ b/fr-fr/csharp-fr.html.markdown @@ -0,0 +1,812 @@ +--- +language: c# +contributors: + - ["Irfan Charania", "https://github.com/irfancharania"] + - ["Max Yankov", "https://github.com/golergka"] + - ["Melvyn Laïly", "http://x2a.yt"] + - ["Shaun McCarthy", "http://www.shaunmccarthy.com"] +translators: + - ["Olivier Hoarau", "https://github.com/Olwaro"] +filename: LearnCSharp.cs +lang: fr-fr +--- + +C# est un langage de programmation orienté objet à typage fort qui permet aux développeurs de créer une grande variété d'applications fiables et robustes s'appuyant sur le framework .NET. + +[Plus d'infos](http://msdn.microsoft.com/fr-fr/library/67ef8sbd.aspx) + +```c# +// Les commentaires sur une seule ligne commencent par // +/* +Les +commentaires +multi-lignes +ressemblent +à +ceci +*/ +/// <summary> +/// Ceci est un commentaire de documentation XML +/// </summary> + +// Importez des namespaces avec l'instruction 'using' +using System; +using System.Collections.Generic; +using System.Data.Entity; +using System.Dynamic; +using System.Linq; +using System.Linq.Expressions; +using System.Net; +using System.Threading.Tasks; + +// Définit la portée du code pour une meilleure organisation +namespace Learning +{ + // Chaque fichier .cs devrait au moins contenir une classe avec le même nom + // que celui du fichier. Ce n'est pas une obligation mais c'est mieux ! + public class LearnCSharp + { + // LES BASES - si vous avez déjà de l'expérience en Java ou C++ + // passez directement à la partie FONCTIONNALITÉS INTERÉSSANTES + public static void Syntax() + { + // Utilisez Console.WriteLine pour écrire sur la sortie + Console.WriteLine("Hello World"); + Console.WriteLine( + "Entier: " + 10 + + " Double: " + 3.14 + + " Booleen: " + true); + + // Pour omettre le retour à la ligne : Console.Write + Console.Write("Hello "); + Console.Write("World"); + + /////////////////////////////////////////////////// + // Types et Variables + // Déclarez une variable avec la syntaxe <type> <nom> + /////////////////////////////////////////////////// + + // Sbyte - Entier signé sur 8 bits + // (-128 <= sbyte <= 127) + sbyte fooSbyte = 100; + + // Byte - Entier non-signé sur 8 bits + // (0 <= byte <= 255) + byte fooByte = 100; + + // Short - Entier sur 16 bits + // Signé - (-32,768 <= short <= 32,767) + // Non-signé - (0 <= ushort <= 65,535) + short fooShort = 10000; + ushort fooUshort = 10000; + + // Int - Entier sur 32 bits + int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647) + uint fooUint = 1; // (0 <= uint <= 4,294,967,295) + + // Long - Entier sur 64 bits + long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) + ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615) + // Par défaut le type d'un littéral entier est int ou uint + // on ajoute 'L' pour spécifier la création d'un long + + // Double - Réel sur 64 bits en virgule flottante (norme IEEE 754) + double fooDouble = 123.4; // Precision : 15-16 chiffres + + // Float - Réel sur 32 bits en virgule flottante (norme IEEE 754) + float fooFloat = 234.5f; // Precision : 7 chiffres + // Par défaut le type d'un littéral réel est double + // on ajoute 'f' pour spécifier la création d'un float + + // Decimal - Type de donnée numérique sur 128 bits, fournit une plus + // grande précision et une plage de valeurs réduite. + // Approprié aux calculs financiers et monétaires + decimal fooDecimal = 150.3m; + + // Booléen - vrai / faux + bool fooBoolean = true; // ou false + + // Char - Un unique caractère Unicode sur 16 bits + char fooChar = 'A'; + + // String -- contrairement aux types précédents qui sont des types valeurs, + // string est un type référence. Il peut donc avoir la valeur null + string fooString = "\"échappement\" de guillemets et ajout de \n (nouvelle ligne) et de \t (tabulation)"; + Console.WriteLine(fooString); + + // Il est possible d'accéder à chaque caractère d'une chaîne de caractères via son index + char charFromString = fooString[1]; // 'é' + // une chaîne de caractères est immuable : impossible de faire fooString[1] = 'X'; + + // Comparaison de chaînes de caractères avec la culture courrante en ignorant la casse + string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase); + + // Formatage + string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2); + + // Dates et formatage + DateTime fooDate = DateTime.Now; + Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy")); + + // Il est possible d'étaler une chaîne de caractères sur plusieurs lignes avec le symbole @. + // Pour échapper " utilisez "" + string bazString = @"Voici quelques trucs +sur une nouvelle ligne! ""Wow!"", quel style"; + + // Utilisez const ou read-only pour rendre une variable immuable. + // Les valeurs constantes sont calculées au moment de la compilation + const int HOURS_I_WORK_PER_WEEK = 9001; + + /////////////////////////////////////////////////// + // Structures de données + /////////////////////////////////////////////////// + + // Tableaux - indexé à partir de zéro + // La taille d'un tableau doit être décidée à la déclaration + // La syntaxe pour déclarer un tableau est la suivante : + // <type>[] <nom> = new <type>[<taille>] + int[] intArray = new int[10]; + + // Une autre méthode de déclaration et d'initialisation + int[] y = { 9000, 1000, 1337 }; + + // Indexer un tableau - Accéder à un élément + Console.WriteLine("intArray à 0: " + intArray[0]); + // Les tableaux sont muables. + intArray[1] = 1; + + // Listes + // Elles sont plus souvent utilisées que les tableaux car plus souples + // La syntaxe pour déclarer une liste est la suivante : + // List<type> <nom> = new List<type>(); + List<int> intList = new List<int>(); + List<string> stringList = new List<string>(); + List<int> z = new List<int> { 9000, 1000, 1337 }; // intialisation + // Les <> indiquent un type générique + // Pus d'info dans la partie FONCTIONNALITÉS INTERÉSSANTES + + // Les éléments d'une liste ne sont pas null par défaut + // Il faut ajouter une valeur avant d'y accéder par index + intList.Add(1); + Console.WriteLine("intList à 0: " + intList[0]); + + // Autres structures de données à étudier : + // Stack/Queue (Pile/File) + // Dictionary (une implémentation de hash map) + // HashSet (représente un ensemble) + // Collections en lecture seule + // Tuple (.Net 4+) + + /////////////////////////////////////// + // Opérateurs + /////////////////////////////////////// + Console.WriteLine("\n->Opérateurs"); + + int i1 = 1, i2 = 2; // Raccourci pour des déclarations multiples + + // Arithmétique classique + Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3 + + // Modulo + Console.WriteLine("11%3 = " + (11 % 3)); // => 2 + + // Opérateurs de comparaison + Console.WriteLine("3 == 2? " + (3 == 2)); // => False + Console.WriteLine("3 != 2? " + (3 != 2)); // => True + Console.WriteLine("3 > 2? " + (3 > 2)); // => True + Console.WriteLine("3 < 2? " + (3 < 2)); // => False + Console.WriteLine("2 <= 2? " + (2 <= 2)); // => True + Console.WriteLine("2 >= 2? " + (2 >= 2)); // => True + + // Opérateurs bit à bit ! + /* + ~ Compément unaire + << Décalage à gauche + >> Décalage à droite + & ET logique + ^ OU exclusif + | OU inclusif + */ + + // Incrémentations + int i = 0; + Console.WriteLine("\n->Inc/Dec-rementation"); + Console.WriteLine(i++); //i = 1. Post-Incrémentation + Console.WriteLine(++i); //i = 2. Pre-Incrémentation + Console.WriteLine(i--); //i = 1. Post-Decrémentation + Console.WriteLine(--i); //i = 0. Pre-Decrémentation + + /////////////////////////////////////// + // Structures de contrôle + /////////////////////////////////////// + Console.WriteLine("\n->Structures de contrôle"); + + // Structure conditionnelle + int j = 10; + if (j == 10) + { + Console.WriteLine("Je serai affiché"); + } + else if (j > 10) + { + Console.WriteLine("Pas moi"); + } + else + { + Console.WriteLine("Moi non plus"); + } + + // Opérateur ternaire + // Un simple if/else peut s'écrire : + // <condition> ? <valeur si true> : <valeur si false> + string isTrue = (true) ? "True" : "False"; + + // Boucle while + int fooWhile = 0; + while (fooWhile < 100) + { + // 100 passages, de 0 à 99 + fooWhile++; + } + + // Boucle Do While + int fooDoWhile = 0; + do + { + // 100 passages, de 0 à 99 + fooDoWhile++; + } while (fooDoWhile < 100); + + // Boucle for + // Structure : for(<etat_initial>; <condition>; <pas>) + for (int fooFor = 0; fooFor < 10; fooFor++) + { + // 10 passages, de 0 à 9 + } + + // La boucle foreach + // Structure : foreach(<type_iterateur> <nom_iterateur> in <enumerable>) + // Cette boucle est utilisable sur des objets implémentant IEnumerable ou IEnumerable<T> + // Toutes les collections du framework .NET (Tableaux, Listes, ...) implémentent ces interfaces. + // (Notez que dans l'exemple suivant .ToCharArray() peut être omit car + // string implémente IEnumerable) + foreach (char character in "Hello World".ToCharArray()) + { + //Itération sur chaque caractère + } + + // La structure Switch Case + // Un switch fonctionne avec les types : byte, short, char et int. + // Les enums sont aussi supportés ainsi que les chaînes de caractères et quelques + // classes spéciales basées sur les types primitifs : Character, Byte, Short et Integer. + int mois = 3; + string moisString; + switch (mois) + { + case 1: + moisString = "Janvier"; + break; + case 2: + moisString = "Février"; + break; + case 3: + moisString = "Mars"; + break; + + // Vous pouvez assigner plus d'un 'case' à une action + // Mais vous ne pouvez pas ajouter une action sans 'break' avant un 'case' + // (pour ce faire, il faudrait ajouter explicitement un 'goto case x') + case 6: + case 7: + case 8: + moisString = "C'est l'été!"; + break; + default: + moisString = "Un autre mois oO"; + break; + } + + /////////////////////////////////////// + // conversion de type de donnée et transtypage + /////////////////////////////////////// + + // conversion de string vers int + // lève une exception en cas d'erreur + int.Parse("123"); //retourne la valeur entière de "123" + + // TryParse affecte la valeur par défaut du type en cas d'erreur + // dans ce cas : 0 + int tryInt; + if (int.TryParse("123", out tryInt)) // La fonction retourne un booléen + Console.WriteLine(tryInt); // => 123 + + // conversion d'un entier vers une chaîne de caractères + // La classe Convert possède plusieurs méthodes pour faciliter la conversion + Convert.ToString(123); + // ou + tryInt.ToString(); + } + + /////////////////////////////////////// + // CLASSES - voir les définitions à la fin du fichier + /////////////////////////////////////// + + public static void Classes() + { + // voir les déclarations à la fin du fichier + + // Utilisez 'new' pour instancier une classe + Bicycle trek = new Bicycle(); + + // Appel des méthodes de l'objet + trek.SpeedUp(3); // Il est toujours bon d'utiliser des accesseurs + trek.Cadence = 100; + + // Affichage de la valeur de retour d'une méthode. + Console.WriteLine("trek info: " + trek.Info()); + + // Instanciation d'un nouveau PennyFarthing + PennyFarthing funbike = new PennyFarthing(1, 10); + Console.WriteLine("funbike info: " + funbike.Info()); + + Console.Read(); + } + + // POINT D'ENTRÉE - Une application console doit avoir une méthode main comme point d'entrée + public static void Main(string[] args) + { + OtherInterestingFeatures(); + } + + // + // FONCTIONNALITÉS INTÉRÉSSANTES + // + + // SIGNATURE DE METHODE + public // Visibilité + static // Permet un appel direct par la classe (sans instanciation) + int // Type de retour, + MethodSignatures( + int maxCount, // Premier paramètre, de type int + int count = 0, // Valeur par défaut si aucun argument n'est passé + int another = 3, + params string[] otherParams // Capture tous les arguments passés à la méthode + ) + { + return -1; + } + + // Des méthodes peuvent avoir le même nom tant que leur signature est unique + public static void MethodSignature(string maxCount) + { + } + + // TYPE GÉNÉRIQUE + + // Les types TKey et TValue sont spécifiés par l'utilisateur lors de l'appel de la fonction + // Cette méthode émule SetDefaut de Python + public static TValue SetDefault<TKey, TValue>( + IDictionary<TKey, TValue> dictionary, + TKey key, + TValue defaultItem) + { + TValue result; + if (!dictionary.TryGetValue(key, out result)) + return dictionary[key] = defaultItem; + return result; + } + + // Vous pouvez limiter les types autorisés + public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int> + { + // Nous sommes sûrs de pouvoir itérer, car T implémente IEnumerable<int> + foreach (var item in toPrint) + // Item sera de type int + Console.WriteLine(item.ToString()); + } + + public static void OtherInterestingFeatures() + { + // PARAMÈTERES OPTIONNELS + MethodSignatures(3, 1, 3, "Des", "Paramètres", "En plus"); + MethodSignatures(3, another: 3); // affectation explicite, les autres + // paramètres ont la valeur par défaut + + // MÉTHODE D'EXTENSION + int i = 3; + i.Print(); // Définit plus bas + + // TYPES NULLABLE - idéal pour les interactions avec une base de données ou pour les valeurs de retour + // Tous les types valeurs peuvent être rendus nullable en les suffixant par '?' + // <type>? <nom> = <value> + int? nullable = null; // raccourci pour Nullable<int> + Console.WriteLine("Nullable variable: " + nullable); + bool hasValue = nullable.HasValue; // retourne vrai si la valeur n'est pas null + + // ?? est un sucre syntaxique pour spécifier une valeur par défaut + // au cas ou une autre valeur serait nulle + int notNullable = nullable ?? 0; // 0 + + // VARIABLES IMPLICITEMENT TYPÉES - vous pouvez laisser le compilateur deviner le type d'une variable + var magic = "magic est de type string à la compilation. On a toujours un typage fort !"; + // magic = 9; // ne fonctionnera pas car magic est désormais une chaîne de caractères + + // TYPES GÉNÉRIQUES + var agenda = new Dictionary<string, string>() { + {"Sarah", "212 555 5555"} // Ajout d'une entrée à notre agenda + }; + + // Appel de la fonction SetDefault (définie plus haut) + Console.WriteLine(SetDefault<string,string>(agenda, "Shaun", "Pas de numéro")); // => Pas de numéro + // Notez que vous n'avez pas à spécifier TKey et TValue car le compilateur saura les inférer. + Console.WriteLine(SetDefault(agenda, "Sarah", "No Phone")); // => 212 555 5555 + + // EXPRESSION LAMBDA - permet d'écrire une fonction en tant qu'expression + Func<int, int> square = (x) => x * x; // La dernière expression est la valeur de retour + Console.WriteLine(square(3)); // => 9 + + // GESTION AUTOMATIQUE DES RESSOURCES - vous permet de manipuler facilement des resources non-managées + // La plus part des objets qui accèdent à des ressources non-managées (handle de fichier, périphérique, etc.) + // implémentent l'interface IDisposable. L'instruction using prend soin + // de libérer les objets IDisposable proprement à votre place. + using (StreamWriter writer = new StreamWriter("log.txt")) + { + writer.WriteLine("Rien à signaler"); + // À la fin de cette portée les ressources seront libérées. + // Même si une exception est levée. + } + + // BIBLIOTHÈQUE DE TÂCHES PARALLÈLES (TPL) + // http://msdn.microsoft.com/fr-fr/library/dd460717.aspx + var websites = new string[] { + "http://www.google.com", "http://www.reddit.com", + "http://www.shaunmccarthy.com" + }; + var responses = new Dictionary<string, string>(); + + // L'exemple suivant exécutera chaque requête dans un thread séparé, + // et attendra la fin de chacun d'entre eux avant de continuer + Parallel.ForEach(websites, + new ParallelOptions() {MaxDegreeOfParallelism = 3}, // maximum de 3 threads + website => + { + // Fait quelque chose de long + using (var r = WebRequest.Create(new Uri(website)).GetResponse()) + { + responses[website] = r.ContentType; + } + }); + + // Ceci ne s'exécutera pas tant que les threads n'auront pas fini leur travail + foreach (var key in responses.Keys) + Console.WriteLine("{0}:{1}", key, responses[key]); + + // TYPE DYNAMIQUE - idéal pour travailler avec d'autres langages + dynamic student = new ExpandoObject(); + student.FirstName = "Mon prénom"; // Pas besoin de définir l'objet + + // Vous pouvez même ajouter des méthodes (dans cet exemple : la méthode prend une chaîne de caractères et retourne une chaîne de caractères) + student.Introduce = new Func<string, string>( + (introduceTo) => string.Format("Hey {0}, c'est {1}", student.FirstName, introduceTo)); + Console.WriteLine(student.Introduce("Beth")); + + // IQUERYABLE<T> - quasiment toutes les collections implémentent cette interface + // ce qui permet d'utiliser des méthodes de style 'Filter' / 'Map' / 'Reduce' + var bikes = new List<Bicycle>(); + bikes.Sort(); // Trie le tableau sur place + bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // Trie en se basant sur la propriété Wheels + var result = bikes + .Where(b => b.Wheels > 3) // 'Filter' - enchaînable (retourne un IQueryable du type précédent) + .Where(b => b.IsBroken && b.HasTassles) + .Select(b => b.ToString()); // 'Map' - on retourne le .ToString() de chaque élément filtré, + // le résultat est un IQueryable<string> + + var sum = bikes.Sum(b => b.Wheels); // 'Reduce' - fait la somme de tous les Wheels de la liste + + // Creation d'une liste d'objet anonymes basés sur des paramètres de la classe Bike + var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles }); + // Le compilateur peut inférer le type de ces objets anonymes, permettant à certains IDE d'effectuer + // des autos-complétion. + foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome)) + Console.WriteLine(bikeSummary.Name); + + + // ASPARALLEL + // C'est ici que les choses se compliquent - un mélange de LINQ et de TPL + var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name); + // La ligne précédente s'exécute en parallèle ! Des threads seront gérés automatiquement + // et les données y seront réparties. Idéal sur de grosses données (et si votre + // machine dispose de plusieurs coeurs) + + + // LINQ - lie une source de données à des objets IQueryable<T> + // ex : LindToSql => liaison avec une base de données, LinqToXml => liaison avec un document xml + var db = new BikeRespository(); + + // l'exécution est décalée, ce qui est préférable quand on travaille sur une base données + var filter = db.Bikes.Where(b => b.HasTassles); // pas de requête exécutée + if (42 > 6) // Vous pouvez continuer à affiner la recherche + filter = filter.Where(b => b.IsBroken); // pas de requête exécutée + + var query = filter + .OrderBy(b => b.Wheels) + .ThenBy(b => b.Name) + .Select(b => b.Name); // toujours pas de requête exécutée + + // Maintenant la requête est exécutée, mais retourne des données uniquement au fil de l'itération + foreach (string bike in query) + Console.WriteLine(result); + + } + + } // Fin de la classe LearnCSharp + + // Il est possible d'inclure plusieurs classes dans un fichier .cs + + public static class Extensions + { + // EXTENSION DE FONCTIONS + public static void Print(this object obj) + { + Console.WriteLine(obj.ToString()); + } + } + + // Syntaxe de déclaration de classe : + // <public/private/protected/internal> class <class name>{ + // // champs, constructeurs, fonctions + // // tout est déclaré et implémenté à l'intérieur + // } + + public class Bicycle + { + // Propriétés et variable de la classe + public int Cadence // Public : peut être accédé de partout + { + get // get - définit une méthode pour lire la propriété + { + return _cadence; + } + set // set - définit une méthode pour affecter une valeur à la propriété + { + _cadence = value; // 'value' est la valeur passée en argument au setteur + } + } + private int _cadence; + + protected virtual int Gear // Protected : accessible depuis la classe et ses classes filles + { + get; // crée une propriété automatique, pas besoin de créer une variable de stockage + set; + } + + internal int Wheels // Internal : accessible depuis l'assembly + { + get; + private set; // Il est possible de choisir la portée d'un accesseur + } + + int _speed; // Par défaut tout est privé au sein d'une classe : accessible uniquement depuis la classe + // on peut ajouter explicitement le mot clé 'private' + + public string Name { get; set; } + + + // Enum est un type valeur formé par un ensemble de constantes nommées + // C'est simplement une manière de mettre un nom sur une valeur (int par défaut). + // Les types compatibles pour un enum sont : byte, sbyte, short, ushort, int, uint, long et ulong. + // Un enum ne peut pas contenir deux fois la même valeur + public enum BikeBrand + { + AIST, + BMC, + Electra = 42, // il est possible de donner explicitement une valeur + Gitane // 43 + } + // Nous avons défini cet enum à l'intérieur de la classe Bicycle, c'est donc un type imbriqué + // Pour le référencer à l'extérieur, il faudra utiliser Bicycle.BikeBrand + + public BikeBrand Brand; // Après avoir déclaré notre type enum, on peut créer un champ de ce type + + // Les membres statiques appartiennent à une classe plutôt qu'à une instance particulière + // Il est possible d'y accéder sans passer par un objet : + // ex : Console.WriteLine("Bicycles créés : " + Bicycle.bicyclesCreated); + static public int BicyclesCreated = 0; + + // Les valeurs en lecture seule sont affectées lors de l'exécution + // Elles ne peuvent être assignées que lors de leur déclaration ou dans un constructeur + readonly bool _hasCardsInSpokes = false; // variable en lecture et privée + + // Les constructeurs sont un moyen de créer des objets + // Voici un constructeur par défaut (pas d'arguments) + public Bicycle() + { + this.Gear = 1; // accès aux membres de la classe via le mot clé this + Cadence = 50; // qui est souvent implicite + _speed = 5; + Name = "Bontrager"; + Brand = BikeBrand.AIST; + BicyclesCreated++; + } + + // Voici un constructeur spécifique (qui prend des arguments) + public Bicycle(int startCadence, int startSpeed, int startGear, + string name, bool hasCardsInSpokes, BikeBrand brand) + : base() // possibilité d'appeler le constructeur de la classe mère (ici Object) + { + Gear = startGear; + Cadence = startCadence; + _speed = startSpeed; + Name = name; + _hasCardsInSpokes = hasCardsInSpokes; + Brand = brand; + } + + // Les constructeurs peuvent s'enchaîner + public Bicycle(int startCadence, int startSpeed, BikeBrand brand) : + this(startCadence, startSpeed, 0, "big wheels", true, brand) + { + } + + // Syntaxe de méthode : + // <public/private/protected> <type de retour> <nom de methode>(<args>) + + // Les classes peuvent implémenter des accesseurs pour leurs champs + // ou implémenter des propriétés (c'est la méthode dominante en C#) + + // Les paramètres de méthodes peuvent avoir des valeurs par défaut + // Dans ce cas, la méthode peut être appelée sans arguments + public void SpeedUp(int increment = 1) + { + _speed += increment; + } + + public void SlowDown(int decrement = 1) + { + _speed -= decrement; + } + + // Les propriétés se chargent de lire/modifier des valeurs + // elles peuvent être en lecture(get), en écriture(set) ou les deux + private bool _hasTassles; // variable privée + public bool HasTassles // propriété publique + { + get { return _hasTassles; } + set { _hasTassles = value; } + } + + // Il est possible de définir une propriété automatique sur une ligne + // cette syntaxe créera une variable de stockage automatiquement. + // Il est possible de modifier l'accèsibilité des getter/setter pour limiter leur utilisation + public bool IsBroken { get; private set; } + + // La même chose sur plusieurs lignes + public int FrameSize + { + get; + // Notez que seule la classe Bicycle peut changer la valeur de FrameSize + private set; + } + + // Méthode qui affiche la valeur des champs de cet objet + public virtual string Info() + { + return "Gear: " + Gear + + " Cadence: " + Cadence + + " Speed: " + _speed + + " Name: " + Name + + " Cards in Spokes: " + (_hasCardsInSpokes ? "yes" : "no") + + "\n------------------------------\n" + ; + } + + // Les méthodes peuvent aussi être statiques. Utile pour les méthodes d'aide. + public static bool DidWeCreateEnoughBycles() + { + // À l'intérieur d'une méthode statique on ne peut que référencer des membres statiques ! + return BicyclesCreated > 9000; + } // Si votre classe n'a que des membres statiques, marquez la comme statique + + } // fin de la classe Bicycle + + // PennyFarthing est une classe dérivée de Bicycle + class PennyFarthing : Bicycle + { + // Appel au constructeur de la classe mère + public PennyFarthing(int startCadence, int startSpeed) : + base(startCadence, startSpeed, 0, "PennyFarthing", true, BikeBrand.Electra) + { + } + + protected override int Gear + { + get + { + return 0; + } + set + { + // Lève une exception + throw new ArgumentException("Impossible de modifier Gear sur un PennyFarthing"); + } + } + + public override string Info() + { + string result = "PennyFarthing bicycle "; + result += base.ToString(); // Appel à la version de base de cette méthode + return result; + } + } + + // Les interfaces contiennent uniquement la signature de leurs membres, sans implémentation. + interface IJumpable + { + void Jump(int meters); // Tous les membres d'interface sont publics par défaut + } + + interface IBreakable + { + bool Broken { get; } // Les interfaces peuvent contenir des propriétés, + // des méthodes et des évènements + } + + // Une classe ne peut hériter que d'une seule autre classe, mais peut implémenter plusieurs interfaces + class MountainBike : Bicycle, IJumpable, IBreakable + { + int damage = 0; + + public void Jump(int meters) + { + damage += meters; + } + + public bool Broken + { + get + { + return damage > 100; + } + } + } + + /// <summary> + /// Utilisé pour illustrer la connexion à une base donnée dans l'exemple LinqToSql + /// L'approche code first d'EntityFramework est très pratique (un peu comme ActiveRecord de Ruby) + /// http://msdn.microsoft.com/fr-fr/data/jj193542.aspx + /// </summary> + public class BikeRespository : DbSet + { + public BikeRespository() + : base() + { + } + + public DbSet<Bicycle> Bikes { get; set; } + } +} // Fin du namespace +``` + +## Sujets non-abordés + + * Flags + * Attribus + * Propriétés statiques + * Exceptions, Abstraction + * ASP.NET (Web Forms/MVC/WebMatrix) + * Winforms + * Windows Presentation Foundation (WPF) + +## Lectures Complémentaires + + * [DotNetPerls](http://www.dotnetperls.com) + * [C# in Depth](http://manning.com/skeet2) + * [Programming C#](http://shop.oreilly.com/product/0636920024064.do) + * [LINQ](http://shop.oreilly.com/product/9780596519254.do) + * [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx) + * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials) + * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials) + * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials) + * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208) + +[Convention de codage C#](http://msdn.microsoft.com/library/vstudio/ff926074) diff --git a/zh-cn/clojure-macro-cn.html.markdown b/zh-cn/clojure-macro-cn.html.markdown new file mode 100644 index 00000000..e1b68a83 --- /dev/null +++ b/zh-cn/clojure-macro-cn.html.markdown @@ -0,0 +1,151 @@ +--- +language: "clojure macros" +filename: learnclojuremacros.clj +contributors: + - ["Adam Bard", "http://adambard.com/"] +translators: + - ["Jakukyo Friel", "http://weakish.github.io"] +--- + +和所有Lisp一样,Clojure内在的[同构性](https://en.wikipedia.org/wiki/Homoiconic)使得你可以穷尽语言的特性,编写生成代码的子过程——“宏”。宏是一种按需调制语言的强大方式。 + +小心!可以用函数完成的事用宏去实现可不是什么好事。你应该仅在需要控制参数是否或者何时eval的时候使用宏。 + +你应该熟悉Clojure.确保你了解[Y分钟学Clojure](http://learnxinyminutes.com/docs/zh-cn/clojure-cn/)中的所有内容。 + +```clojure +;; 使用defmacro定义宏。宏应该输出一个可以作为clojure代码演算的列表。 +;; +;; 以下宏的效果和直接写(reverse "Hello World")一致。 + +(defmacro my-first-macro [] + (list reverse "Hello World")) + +;; 使用macroexpand或macroexpand-1查看宏的结果。 +;; +;; 注意,调用需要引用。 +(macroexpand '(my-first-macro)) +;; -> (#<core$reverse clojure.core$reverse@xxxxxxxx> "Hello World") + +;; 你可以直接eval macroexpand的结果 +(eval (macroexpand '(my-first-macro))) +; -> (\d \l \o \r \W \space \o \l \l \e \H) + +;; 不过一般使用以下形式,更简短,更像函数: +(my-first-macro) ; -> (\d \l \o \r \W \space \o \l \l \e \H) + +;; 创建宏的时候可以使用更简短的引用形式来创建列表 +(defmacro my-first-quoted-macro [] + '(reverse "Hello World")) + +(macroexpand '(my-first-quoted-macro)) +;; -> (reverse "Hello World") +;; 注意reverse不再是一个函数对象,而是一个符号。 + +;; 宏可以传入参数。 +(defmacro inc2 [arg] + (list + 2 arg)) + +(inc2 2) ; -> 4 + +;; 不过,如果你尝试配合使用引用列表,会导致错误, +;; 因为参数也会被引用。 +;; 为了避免这个问题,clojure提供了引用宏的另一种方式:` +;; 在`之内,你可以使用~获得外圈作用域的变量。 +(defmacro inc2-quoted [arg] + `(+ 2 ~arg)) + +(inc2-quoted 2) + +;; 你可以使用通常的析构参数。用~@展开列表中的变量。 +(defmacro unless [arg & body] + `(if (not ~arg) + (do ~@body))) ; 别忘了 do! + +(macroexpand '(unless true (reverse "Hello World"))) + +;; -> +;; (if (clojure.core/not true) (do (reverse "Hello World"))) + +;; 当第一个参数为假时,(unless)会演算、返回主体。 +;; 否则返回nil。 + +(unless true "Hello") ; -> nil +(unless false "Hello") ; -> "Hello" + +;; 需要小心,宏会搞乱你的变量 +(defmacro define-x [] + '(do + (def x 2) + (list x))) + +(def x 4) +(define-x) ; -> (2) +(list x) ; -> (2) + +;; 使用gensym来获得独有的标识符 +(gensym 'x) ; -> x1281 (or some such thing) + +(defmacro define-x-safely [] + (let [sym (gensym 'x)] + `(do + (def ~sym 2) + (list ~sym)))) + +(def x 4) +(define-x-safely) ; -> (2) +(list x) ; -> (4) + +;; 你可以在 ` 中使用 # 为每个符号自动生成gensym +(defmacro define-x-hygenically [] + `(do + (def x# 2) + (list x#))) + +(def x 4) +(define-x-hygenically) ; -> (2) +(list x) ; -> (4) + +;; 通常会配合宏使用帮助函数。 +;; 让我们创建一些帮助函数来支持(无聊的)算术语法: + +(declare inline-2-helper) +(defn clean-arg [arg] + (if (seq? arg) + (inline-2-helper arg) + arg)) + +(defn apply-arg + "Given args [x (+ y)], return (+ x y)" + [val [op arg]] + (list op val (clean-arg arg))) + +(defn inline-2-helper + [[arg1 & ops-and-args]] + (let [ops (partition 2 ops-and-args)] + (reduce apply-arg (clean-arg arg1) ops))) + +;; 在创建宏前,我们可以先测试 +(inline-2-helper '(a + (b - 2) - (c * 5))) ; -> (- (+ a (- b 2)) (* c 5)) + +; 然而,如果我们希望它在编译期执行,就需要创建宏 +(defmacro inline-2 [form] + (inline-2-helper form))) + +(macroexpand '(inline-2 (1 + (3 / 2) - (1 / 2) + 1))) +; -> (+ (- (+ 1 (/ 3 2)) (/ 1 2)) 1) + +(inline-2 (1 + (3 / 2) - (1 / 2) + 1)) +; -> 3 (事实上,结果是3N, 因为数字被转化为带/的有理分数) +``` + +## 扩展阅读 + +[Clojure for the Brave and True](http://www.braveclojure.com/)系列的编写宏 +http://www.braveclojure.com/writing-macros/ + +官方文档 +http://clojure.org/macros + +何时使用宏? +http://dunsmor.com/lisp/onlisp/onlisp_12.html diff --git a/zh-cn/visualbasic-cn.html.markdown b/zh-cn/visualbasic-cn.html.markdown new file mode 100644 index 00000000..95f01ed6 --- /dev/null +++ b/zh-cn/visualbasic-cn.html.markdown @@ -0,0 +1,274 @@ +--- +language: Visual Basic +contributors: + - ["Brian Martin", "http://brianmartin.biz"] +translators: + - ["Abner Chou", "http://github.com/NoahDragon"] +lang: zh-cn +filename: learnvisualbasic.vb-cn +--- + +```vb +Module Module1 + + Sub Main() + ' 让我们先从简单的终端程序学起。 + ' 单引号用来生成注释(注意是半角单引号,非全角单引号’) + ' 为了方便运行此示例代码,我写了个目录索引。 + ' 可能你还不了解以下代码的意义,但随着教程的深入, + ' 你会渐渐理解其用法。 + Console.Title = ("Learn X in Y Minutes") + Console.WriteLine("NAVIGATION") ' 显示目录 + Console.WriteLine("") + Console.ForegroundColor = ConsoleColor.Green + Console.WriteLine("1. Hello World Output") ' Hello world 输出示例 + Console.WriteLine("2. Hello World Input") ' Hello world 输入示例 + Console.WriteLine("3. Calculating Whole Numbers") ' 求整数之和 + Console.WriteLine("4. Calculating Decimal Numbers") ' 求小数之和 + Console.WriteLine("5. Working Calculator") ' 计算器 + Console.WriteLine("6. Using Do While Loops") ' 使用 Do While 循环 + Console.WriteLine("7. Using For While Loops") ' 使用 For While 循环 + Console.WriteLine("8. Conditional Statements") ' 条件语句 + Console.WriteLine("9. Select A Drink") ' 选饮料 + Console.WriteLine("50. About") ' 关于 + Console.WriteLine("Please Choose A Number From The Above List") + Dim selection As String = Console.ReadLine + Select Case selection + Case "1" ' Hello world 输出示例 + Console.Clear() ' 清空屏幕 + HelloWorldOutput() ' 调用程序块 + Case "2" ' Hello world 输入示例 + Console.Clear() + HelloWorldInput() + Case "3" ' 求整数之和 + Console.Clear() + CalculatingWholeNumbers() + Case "4" ' 求小数之和 + Console.Clear() + CalculatingDecimalNumbers() + Case "5" ' 计算器 + Console.Clear() + WorkingCalculator() + Case "6" ' 使用 do while 循环 + Console.Clear() + UsingDoWhileLoops() + Case "7" ' 使用 for while 循环 + Console.Clear() + UsingForLoops() + Case "8" ' 条件语句 + Console.Clear() + ConditionalStatement() + Case "9" ' If/Else 条件语句 + Console.Clear() + IfElseStatement() ' 选饮料 + Case "50" ' 关于本程序和作者 + Console.Clear() + Console.Title = ("Learn X in Y Minutes :: About") + MsgBox("This tutorial is by Brian Martin (@BrianMartinn") + Console.Clear() + Main() + Console.ReadLine() + + End Select + End Sub + + ' 一、对应程序目录1,下同 + + ' 使用 private subs 声明函数。 + Private Sub HelloWorldOutput() + ' 程序名 + Console.Title = "Hello World Ouput | Learn X in Y Minutes" + ' 使用 Console.Write("") 或者 Console.WriteLine("") 来输出文本到屏幕上 + ' 对应的 Console.Read() 或 Console.Readline() 用来读取键盘输入 + Console.WriteLine("Hello World") + Console.ReadLine() + ' Console.WriteLine()后加Console.ReadLine()是为了防止屏幕输出信息一闪而过 + ' 类似平时常见的“单击任意键继续”的意思。 + End Sub + + ' 二 + Private Sub HelloWorldInput() + Console.Title = "Hello World YourName | Learn X in Y Minutes" + ' 变量 + ' 用来存储用户输入的数据 + ' 变量声明以 Dim 开始,结尾为 As VariableType (变量类型). + + ' 此教程中,我们希望知道你的姓名,并让程序记录并输出。 + Dim username As String + ' 我们定义username使用字符串类型(String)来记录用户姓名。 + Console.WriteLine("Hello, What is your name? ") ' 询问用户输入姓名 + username = Console.ReadLine() ' 存储用户名到变量 username + Console.WriteLine("Hello " + username) ' 输出将是 Hello + username + Console.ReadLine() ' 暂停屏幕并显示以上输出 + ' 以上程序将询问你的姓名,并和你打招呼。 + ' 其它变量如整型(Integer)我们用整型来处理整数。 + End Sub + + ' 三 + Private Sub CalculatingWholeNumbers() + Console.Title = "Calculating Whole Numbers | Learn X in Y Minutes" + Console.Write("First number: ") ' 输入一个整数:1,2,50,104,等等 + Dim a As Integer = Console.ReadLine() + Console.Write("Second number: ") ' 输入第二个整数 + Dim b As Integer = Console.ReadLine() + Dim c As Integer = a + b + Console.WriteLine(c) + Console.ReadLine() + ' 以上程序将两个整数相加 + End Sub + + ' 四 + Private Sub CalculatingDecimalNumbers() + Console.Title = "Calculating with Double | Learn X in Y Minutes" + ' 当然,我们还需要能够处理小数。 + ' 只需要要将整型(Integer)改为小数(Double)类型即可。 + + ' 输入一个小数: 1.2, 2.4, 50.1, 104.9,等等 + Console.Write("First number: ") + Dim a As Double = Console.ReadLine + Console.Write("Second number: ") ' 输入第二个数 + Dim b As Double = Console.ReadLine + Dim c As Double = a + b + Console.WriteLine(c) + Console.ReadLine() + ' 以上代码能实现两个小数相加 + End Sub + + ' 五 + Private Sub WorkingCalculator() + Console.Title = "The Working Calculator| Learn X in Y Minutes" + ' 但是如果你希望有个能够处理加减乘除的计算器呢? + ' 只需将上面代码复制粘帖即可。 + Console.Write("First number: ") ' 输入第一个数 + Dim a As Double = Console.ReadLine + Console.Write("Second number: ") ' 输入第二个数 + Dim b As Integer = Console.ReadLine + Dim c As Integer = a + b + Dim d As Integer = a * b + Dim e As Integer = a - b + Dim f As Integer = a / b + + ' 通过以下代码我们可以将以上所算的加减乘除结果输出到屏幕上。 + Console.Write(a.ToString() + " + " + b.ToString()) + ' 我们希望答案开头能有3个空格,可以使用String.PadLeft(3)方法。 + Console.WriteLine(" = " + c.ToString.PadLeft(3)) + Console.Write(a.ToString() + " * " + b.ToString()) + Console.WriteLine(" = " + d.ToString.PadLeft(3)) + Console.Write(a.ToString() + " - " + b.ToString()) + Console.WriteLine(" = " + e.ToString.PadLeft(3)) + Console.Write(a.ToString() + " / " + b.ToString()) + Console.WriteLine(" = " + e.ToString.PadLeft(3)) + Console.ReadLine() + + End Sub + + ' 六 + Private Sub UsingDoWhileLoops() + ' 如同以上的代码一样 + ' 这次我们将询问用户是否继续 (Yes or No?) + ' 我们将使用Do While循环,因为我们不知到用户是否需要使用一次以上。 + Console.Title = "UsingDoWhileLoops | Learn X in Y Minutes" + Dim answer As String ' 我们使用字符串变量来存储answer(答案) + Do ' 循环开始 + Console.Write("First number: ") + Dim a As Double = Console.ReadLine + Console.Write("Second number: ") + Dim b As Integer = Console.ReadLine + Dim c As Integer = a + b + Dim d As Integer = a * b + Dim e As Integer = a - b + Dim f As Integer = a / b + + Console.Write(a.ToString() + " + " + b.ToString()) + Console.WriteLine(" = " + c.ToString.PadLeft(3)) + Console.Write(a.ToString() + " * " + b.ToString()) + Console.WriteLine(" = " + d.ToString.PadLeft(3)) + Console.Write(a.ToString() + " - " + b.ToString()) + Console.WriteLine(" = " + e.ToString.PadLeft(3)) + Console.Write(a.ToString() + " / " + b.ToString()) + Console.WriteLine(" = " + e.ToString.PadLeft(3)) + Console.ReadLine() + ' 询问用户是否继续,注意大小写。 + Console.Write("Would you like to continue? (yes / no)") + ' 程序读入用户输入 + answer = Console.ReadLine() ' added a bracket here + ' 当用户输入"yes"时,程序将跳转到Do,并再次执行 + Loop While answer = "yes" + + End Sub + + ' 七 + Private Sub UsingForLoops() + ' 有一些程序只需要运行一次。 + ' 这个程序我们将实现从10倒数计数. + + Console.Title = "Using For Loops | Learn X in Y Minutes" + ' 声明变量和Step (步长,即递减的速度,如-1,-2,-3等)。 + For i As Integer = 10 To 0 Step -1 + Console.WriteLine(i.ToString) ' 将计数结果输出的屏幕 + Next i ' 计算新的i值 + Console.WriteLine("Start") + Console.ReadLine() + End Sub + + ' 八 + Private Sub ConditionalStatement() + Console.Title = "Conditional Statements | Learn X in Y Minutes" + Dim userName As String = Console.ReadLine + Console.WriteLine("Hello, What is your name? ") ' 询问用户姓名 + userName = Console.ReadLine() ' 存储用户姓名 + If userName = "Adam" Then + Console.WriteLine("Hello Adam") + Console.WriteLine("Thanks for creating this useful site") + Console.ReadLine() + Else + Console.WriteLine("Hello " + userName) + Console.WriteLine("Have you checked out www.learnxinyminutes.com") + Console.ReadLine() ' 程序停止,并输出以上文本 + End If + End Sub + + ' 九 + Private Sub IfElseStatement() + Console.Title = "If / Else Statement | Learn X in Y Minutes" + ' 有时候我们需要考虑多于两种情况。 + ' 这时我们就需要使用If/ElesIf条件语句。 + ' If语句就好似个自动售货机,当用户输入A1,A2,A3,等去选择物品时, + ' 所有的选择可以合并到一个If语句中 + + Dim selection As String = Console.ReadLine() ' 读入用户选择 + Console.WriteLine("A1. for 7Up") ' A1 七喜 + Console.WriteLine("A2. for Fanta") ' A2 芬达 + Console.WriteLine("A3. for Dr. Pepper") ' A3 胡椒医生 + Console.WriteLine("A4. for Diet Coke") ' A4 无糖可乐 + Console.ReadLine() + If selection = "A1" Then + Console.WriteLine("7up") + Console.ReadLine() + ElseIf selection = "A2" Then + Console.WriteLine("fanta") + Console.ReadLine() + ElseIf selection = "A3" Then + Console.WriteLine("dr. pepper") + Console.ReadLine() + ElseIf selection = "A4" Then + Console.WriteLine("diet coke") + Console.ReadLine() + Else + Console.WriteLine("Please select a product") ' 请选择你需要的产品 + Console.ReadLine() + End If + + End Sub + +End Module + +``` + +## 参考 + +我(译注:原作者)在命令行下学习的VB。命令行编程使我能够更好的了解程序编译运行机制,并使学习其它语言变得容易。 + +如果希望进一步学习VB,这里还有更深层次的 <a href="http://www.vbbootcamp.co.uk/" Title="VB教学">VB教学(英文)</a>。 + +所有代码均通过测试。只需复制粘帖到Visual Basic中,并按F5运行即可。 |