- Obtener el ultimo dia del mes
-
Aplica a: C#, .NET
Entrando en la onda de compartir codigo, y creo que es la segunda vez en esta semana que necesito esta funcion
DateTime GetLastDayOf(DateTime date) {
return new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
}
- C# trivia #1: overloads, strings, nullable types
-
esta entra sirve a la vez para probar el mas reciente Windows Live Writer
Tenemos estas clase:
public class Foo {
public void Bar(string x) {
Console.WriteLine("string x was called");
}
public void Bar(int? x) {
Console.WriteLine("int? x was called");
}
}
cual sera la salida a la consola con el siguiente codigo:
Foo f = new Foo();
try {
f.Bar(null);
}
catch {
Console.WriteLine("no method was called");
}
- protected, internal, protected internal... de verdad sabes que hacen?
-
Este articulo aplica a C#
Todos creemos dominar los modificadores de acceso, pero me puedes decir lo que protected internal hace?
apuesto que mas de la mitad de los desarrolladores .NET contestarian incorrectamente, vamos a ver:
- private:
- Este es el nivel de acceso mas restrictivo.
- Es accesible solamente dentro del cuerpo de la clase o estructura en que esta declarado.
- Tipos declarados dentro (nested types) del mismo cuerpo de la clase tambien tienen acceso a los tipos privados.
- public:
- Este es el nivel de acceso con menos restricciones.
- No hay restricciones para accesar miembros publicos, son tan visibles como la clase.
- protected:
- El acceso es limitado a la clase que los contiene o a tipos derivados de la clase.
- Lo cual quiere decir que no puedes crear una instancia de esta clase y accesar los miembros protegidos.
- internal:
- El acceso esta limitado solo al assembly en donde la clase reside.
- protected internal:
- Acceso es limitado a el assembly donde la clase reside o a tipos derivados de la clase.
Este ultimo es bastante capcioso, a primera vista podria parecer que permite acceso solo dentro del assembly donde la clase reside y las clases derivadas, pero el "o" ahi es lo que hace la diferencia, si marcas una propiedad protected internal puede ser usada fuera del assembly actual. basicamente protected sobreescribe internal, asi que ni siquiera estoy seguro de cuando es que se podria usar tal modificador.
pero bueno, regresando al tema, si no me crees eso de protected internal, puedes verificar tu mismo:
Assembly1:
public class Test {
protected internal string prop1;
}
Assembly2://despues de agregar la referencia a Assembly 1
public class Test2: Test {
public string prop2;
public Test2() {
prop2 = prop1; //el acceso a prop1 viene de otro assembly, de un miembro protected internal
}
}
Si esto es nuevo para ti, podrias pensar que es absurdo, entonces como haces que una propiedad sea visible solo en el assembly actual y en las clases derivadas (pero solo de este assembly)?
Pues no es tan complicado, marcas la clase como internal, lo cual restringe el acceso solo al assembly actual, y luego marcas la propiedad como protected, lo cual resulta en acceso desde las clases derivadas pero solo dentro del assembly actual.:
internal class Test {
//accesible solo en este assembly y clases derivadas dentro de este assembly
protected string prop1;
} salu2
- formateando 0, 1 como si, no, etc
-
Esto es algo que todos (los programadores) hemos hecho alguna vez, convertir un valor 0, 1 al equivalente si o no, prendido o apagado, verdadero o falso, valor en un string
pues resulta que hay una funcion en el BCL con la cual podemos hacer exactamente eso, string.Format es dicha funcion
Console.WriteLine(string.Format("{0:si;;no}", 0)); //salida "no"
Console.WriteLine(string.Format("{0:si;;no}", 1)); //salida "si"
y nomas por ver que pasaba
Console.WriteLine(string.Format("{0:si;;no}", -1)); //salida "-si"
...Esas pequeñas cosas
- funcion para generar numeros aleatorios, con todos los digitos distintos
-
El codigo para este articulo aplica a C#
Leyendo blogs, me encontre con este post (en italiano), donde Marco quiere escribir una funcion que le genere numeros aleatorios de 5 digitos, el resultado se requiere en un string, donde todos los digitos son diferentes, es decir, cada numero (de 5 digitos) generado, no puede tener 2 digitos iguales, la funcion que el escribio es la siguiente:
private string GetRandom()
{
Random rn = new Random();
string resultnum=string.Empty;
do
{
string a = rn.Next(0, 9).ToString();
if (resultnum.Contains(a)!=true)
resultnum = resultnum + a;
}
while (resultnum.Lengthreturn resultnum;
}
Inmediatamente me dio curiosidad por ver que areas que podria mejorar, y me puse a escribir una funcion que obtuviera el mismo resultado, pero en forma mas optimizada
cosas que saltan a mi mente inmediatamente son:
- concatenacion de strings
- el loop y la comparacion para encontrar numeros que no tengamos previamente
Entonces lo que quise lograr en mi funcion es: evitar la concatenacion, y ejecutar el loop exactamente 5 veces, esto es el resultado:
static char[] allNumbers = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
Random r = new Random();
public string GetRandom2() {
char[] result = new char[5];
int max = 9, pos=0;
for (int i=1; i//*** swap positions
allNumbers[pos] ^= allNumbers[max];
allNumbers[max] ^= allNumbers[pos];
allNumbers[pos] ^= allNumbers[max--];
}
return new string(result);
} La tecnica que use,
- fue tener un arreglo predefinido de caracteres con todos los digitos,
- luego tengo una variable max que uso para llamar el metodo Random.Next(0, max),
- en cada iteracion del loop decremento esta variable,
- y cambio el numero que resulto elegido a la ultima posicion, con esto lo dejo fuera de las posibilidades para la siguiente llamada
Estos cambios me dieron una ganancia realmente minima (3 milesimas por cada 1000 llamadas), luego se me ocurrio mover la declaracion de la variable Random afuera de la funcion, para que se reusara con cada llamada a este metodo, y eso si que me dio una ganancia tremenda, llamando la funcion 10,000 veces, el metodo original me da 114ms, y el metodo nuevo 6ms, asi que ahi era donde estaba realmente el problema, lo demas es casi insignificante =o(
Seguro alguien mas puede crear una funcion mas rapida, pero yo cumpli mi objetivo =o)
salu2