Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
|
highlevel:csharp:xtra2 [2009/02/10 14:54] alfred |
highlevel:csharp:xtra2 [2020/05/09 09:25] (actual) |
||
|---|---|---|---|
| Línea 2: | Línea 2: | ||
| + | ===== Sockets ===== | ||
| + | * [[code:tools#sockets|Explicación de sockets]]. | ||
| + | ==== Creación de un servidor RAW ==== | ||
| + | <code csharp> | ||
| + | System.Net.Sockets.TcpListener server = new System.Net.Sockets.TcpListener(System.Net.IPAddress.Any, 2005); | ||
| + | server.Start(); | ||
| + | Byte[] bytes = new Byte[256]; | ||
| + | String data = null; | ||
| + | while (true) | ||
| + | { | ||
| + | System.Net.Sockets.TcpClient client = server.AcceptTcpClient(); | ||
| + | data = null; | ||
| + | System.Net.Sockets.NetworkStream stream = client.GetStream(); | ||
| + | int i; | ||
| + | while ((i = stream.Read(bytes, 0, bytes.Length)) != 0) | ||
| + | { | ||
| + | data = System.Text.Encoding.ASCII.GetString(bytes, 0, i); | ||
| + | Console.WriteLine("Received: {0}", data); | ||
| + | data = data.ToUpper(); | ||
| + | byte[] msg = System.Text.Encoding.ASCII.GetBytes(data); | ||
| + | stream.Write(msg, 0, msg.Length); | ||
| + | Console.WriteLine("Sent: {0}", data); | ||
| + | } | ||
| + | } | ||
| + | </code> | ||
| + | Para enviar un "salto de línia" haremos: | ||
| + | <code csharp> | ||
| + | byte[] msg = System.Text.Encoding.ASCII.GetBytes(data + "\n\r"); | ||
| + | stream.Write(msg, 0, msg.Length); | ||
| + | </code> | ||
| + | ===== Expresiones Regulares ===== | ||
| + | ==== In a nutshell ==== | ||
| + | En ''System.Text.RegularExpressions'' existe la clase ''Regex'' que se encarga de localizar combinaciones (matches) de expresiones regulares en un texto. Por ejemplo, su método estático ''Matches'' recibe un texto y una expresión regular y devuelve objetos ''Match'' de las coincidencias. \\ | ||
| + | Un objeto ''Match'' tiene las siguientes propiedades interesantes: | ||
| + | * ''NextMatch()'': | ||
| + | * ''Index'': Posición dentro del string original donde se encuentra el primer carácter de la coincidencial. | ||
| + | * ''Lenght'': | ||
| + | * ''Success'': | ||
| + | * ''Value'': Recoge el substring de la coincidencia encontrada. | ||
| - | + | <code csharp> | |
| - | + | string startBy = "src=\"|src = \"|src= \"|src =\""; | |
| + | var matches = System.Text.RegularExpressions.Regex.Matches(text, startBy, System.Text.RegularExpressions.RegexOptions.IgnoreCase); | ||
| + | List<string> lImgNames = new List<string>(); | ||
| + | for (int i = 0; i < matches.Count; i++) | ||
| + | { | ||
| + | var match = matches[i]; | ||
| + | int start = match.Index + match.Value.Length; | ||
| + | int end = text.IndexOf("\"", start); | ||
| + | string file = text.Substring(start, end - start); | ||
| + | lImgNames.Add(file); | ||
| + | } | ||
| + | </code> | ||
| ===== Comunicación entre procesos ===== | ===== Comunicación entre procesos ===== | ||
| + | |||
| Línea 64: | Línea 114: | ||
| === El cliente === | === El cliente === | ||
| + | Únicamente es necesario acceder al objeto a partir de ''Activator.GetObject''. | ||
| <code csharp> | <code csharp> | ||
| - | IpcClientChannel icc = new IpcClientChannel(); | + | // IpcClientChannel icc = new IpcClientChannel(); |
| - | ChannelServices.RegisterChannel(icc, true); | + | // ChannelServices.RegisterChannel(icc, true); |
| - | RemotingConfiguration.RegisterWellKnownClientType(typeof(SharedObjects.Class1), "ipc://myChannel/sharedObjs"); | + | // RemotingConfiguration.RegisterWellKnownClientType(typeof(SharedObjects.Class1), "ipc://myChannel/sharedObjs"); |
| SharedObjects.Class1 c = (SharedObjects.Class1)Activator.GetObject(typeof(SharedObjects.Class1), "ipc://myChannel/sharedObjs"); | SharedObjects.Class1 c = (SharedObjects.Class1)Activator.GetObject(typeof(SharedObjects.Class1), "ipc://myChannel/sharedObjs"); | ||
| Console.WriteLine(c.Value); | Console.WriteLine(c.Value); | ||
| Línea 73: | Línea 124: | ||
| ===== Configuración ===== | ===== Configuración ===== | ||
| + | |||
| + | |||
| + | |||
| + | |||
| ==== Fichero app.config ==== | ==== Fichero app.config ==== | ||
| Línea 88: | Línea 143: | ||
| Utilizaremos un objeto de la clase **AppSettingsReader** y su método ''GetValue'': | Utilizaremos un objeto de la clase **AppSettingsReader** y su método ''GetValue'': | ||
| <code csharp> | <code csharp> | ||
| - | new System.Configuration.AppSettingsReader().GetValue("logFile", typeof(String)) | + | (string)new System.Configuration.AppSettingsReader().GetValue("dbFile", typeof(String)); |
| </code> | </code> | ||
| === Agregar secciones === | === Agregar secciones === | ||
| Línea 105: | Línea 160: | ||
| </configuration> | </configuration> | ||
| </code> | </code> | ||
| - | Para leer estas secciones | + | Para leer estas secciones deberemos agregar la referencia al ensamblado ''System.Configuration'' y poder así utilizar la clase ''ConfigurationManager'': |
| + | <code csharp> | ||
| + | IDictionary confTable = (IDictionary)System.Configuration.ConfigurationManager.GetSection("log"); | ||
| + | string logFile = (string)confTable["logFile"]; | ||
| + | </code> | ||
| + | === Agregar grupos de secciones === | ||
| + | Podemos agregar grupos de secciones, por ejemplo: | ||
| + | <code xml> | ||
| + | <?xml version="1.0" encoding="utf-8" ?> | ||
| + | <configuration> | ||
| + | <configSections> | ||
| + | <sectionGroup name="atm.ws"> | ||
| + | <section name="dbInfo" type="System.Configuration.DictionarySectionHandler" /> | ||
| + | </sectionGroup> | ||
| + | </configSections> | ||
| + | <atm.ws> | ||
| + | <dbInfo> | ||
| + | <add key="DataSource" value="TheDataSource" /> | ||
| + | <add key="UserName" value="user" /> | ||
| + | <add key="Password" value="pass" /> | ||
| + | </dbInfo> | ||
| + | </atm.ws> | ||
| + | ... | ||
| + | </code> | ||
| + | Y luego acceder a ellas como si accediesemos a una sección personalizada: | ||
| + | <code csharp> | ||
| + | IDictionary confTable = (IDictionary)System.Configuration.ConfigurationManager.GetSection("atm.ws/dbInfo"); | ||
| + | string dataSource = (string)confTable["DataSource"]; | ||
| + | </code> | ||
| + | |||
| + | |||
| + | |||
| + | ===== Programación declarativa con C# ===== | ||
| + | * [[code:best-practices#programacion_declarativa|Programación declarativa]] | ||
| + | ==== Métodos ==== | ||
| + | Podemos realizar un bucle ''foreach'' con el método ''List<T>.ForEac'' y una expresión lambda. | ||
| + | <code csharp> | ||
| + | using System; | ||
| + | using System.Collections.Generic; | ||
| + | |||
| + | class Example | ||
| + | { | ||
| + | static void Main() | ||
| + | { | ||
| + | new List<Int32> { 1, 2, 3 } | ||
| + | .ForEach(i => Console.WriteLine(i)); | ||
| + | } | ||
| + | } | ||
| + | </code> | ||
| + | De una forma parecida podemos sacar partido del delagado ''Action<T>'', el cual permite una funcion ''Action<Int32>'' el cual encaja con ''Console.WriteLine''. | ||
| + | <code csharp> | ||
| + | using System; | ||
| + | using System.Collections.Generic; | ||
| + | |||
| + | class Example | ||
| + | { | ||
| + | static void Main() | ||
| + | { | ||
| + | new List<Int32> { 1, 2, 3 } | ||
| + | .ForEach(Console.WriteLine); | ||
| + | } | ||
| + | } | ||
| + | </code> | ||
| + | También el método ''Enumerable.Range'': | ||
| + | <code csharp> | ||
| + | using System; | ||
| + | using System.Linq; | ||
| + | |||
| + | class Example | ||
| + | { | ||
| + | static void Main() | ||
| + | { | ||
| + | Int32 sum = Enumerable.Range(0, 99) | ||
| + | .Where(i => i % 2 == 0) | ||
| + | .Sum(); | ||
| + | Console.WriteLine(sum); | ||
| + | } | ||
| + | } | ||
| + | </code> | ||