jueves, 28 de febrero de 2008

Revisión de Resharper 3.0 de JetBrains

Tuve la oportunidad de utilizar este add-in en mi actual empleo. En mi empleo anterior habia tenido la oportunidad de utilizarlo en su versión 2.5 y los resultados habían sido muy buenos. Con esta nueva versión que nos provee JetBrains, mis expectativas han sido superadas.

Para conseguirlo visiten http://www.jetbrains.com/resharper/

Las principales ventajas que he encontrado a este producto son las siguientes:
* Es tanto una herramienta para ser utilizada en tareas de refactoring sino que incrementa la calidad de nuestro código.
* Está perfectamente integrada con el IDE de desarrollo de Visual Studio 2005
* Implementa las mejores prácticas de programación para brindarnos sugerencias a la hora de escribir código.
* Posee una API abierta lo cual posibilita la creación de plugins de terceras partes.



Como no existe el producto perfecto, las desventajas también existen:
* Las herramientas para test de unidad (UT) no se integran con Visual Studio Team Suite. Esto podría solucionarse con productos de terceras partes.
* Si bien es mucho más ágil que la versión anterior, aún tiene algunos aspectos de performance que por lo general se mitigan agregando mas RAM.
* Las reglas de análisis de código parecen no ser personalizables y digo parecen porque no lo he podido lograr aún anque necesita mas investigación.

Mas allá de estas desventajas, se trata de un producto que me resultó de mucha utilidad y ayuda.
Con esta entrada del blog comienzo una serie de entradas en las que voy a mostrar algunas de las características que he tenido la oportunidad de utilizar, testear y aprovechar. Vamos a comenzar separando las prestaciones en diferentes categorías:


I) Categoría: Análisis de Código
a) Análisis dinámico de código
Resharper detecta de forma automática e instantánea errores en nuestro código y lo resalta sin que tengamos la necesidad de compilar siquiera. Realiza esta operación mientras estamos trabajando. Si posicionamos el mouse en la sección resaltada aparece un tooltip con la descripción del error

b) Advertencias
Además de los errores y advertencias que son detectables por el compilador, Resharper nos provee advertencias adicionales que pueden llegar a ser errores reaales de código.
Por citar algunos ejemplos nos brinda avisos de casteos redundantes, formateo incorrecto de strings, variables locales declaradas pero nunca utilizadas, etc

c) Sugerencias de Código
Resharper realiza un análisis en profundidad en la estructura de nuestro código activando sugerencias de código, las cuales no representan que existen errores pero nos proporciona información que es muy útil conocer, dado que están basadas en las mejores prácticas de diseño.





d) Quick-fixes
Cuando Resharper detecta un error, lo señaliza a traves del ícono de una lampara roja en la parte izquierda de la linea que contiene el error. A través de un shortccut (ALT+ENTER) aparecen las diferentes opciones de fix y al seleccionar la opción que mejor se adecua a nuestras necesidades se corrige automáticamente.


e) Indicador de estado
Al abrir un archivo, Resharper ejecuta un análisas en profundidad utilizando las reglas y mejores prácticas y nos informa a traves de códigos de colores el "estado de salud" del código que contiene nuestro archivo. Este indicador de estado lo encontramos en la esquina superior derecha del archivo, pero adicionalmente posee indicadores de color en cada linea (también en la parte derecha de nuestro editor).


f) Análisis de valor
Este tipo de análisis está relacionado a los valores de nuestras variables y objetos. Es utilizada principalmente para detectar valores que pueden estar seteados a null y brindar un aviso inmediatamente. Otra utilización frecuente es avisarnos de que una variable del tipo boolean está siempre seteada a true o a false.


miércoles, 31 de octubre de 2007

Sistema de Archivos: Unidades de Disco

La clase DriveInfo nos brinda los elementos necesarios para poder acceder a la información de las unidades disponibles en nuestro sistema. esto incluye no solo los discos rigidos, sino las unidades de red que tengamos mapeadas, unidades extraibles, etc.-

Esta clase posee un único metodo estático (GetDrives()) el cual devuelve la lista de todas las unidades de nuestro sistema.

Las instancias de esta clase cuentan con las siguientes propiedades:
- AvailableFreeSpace: Retorna el espacio disponible de una unidad (en bytes). Puede diferir del valor retornado por TotalFreeSpace, dependiendo de las cuotas de discos.
- DriveFormat: Retorna el formato de la unidad tal como FAT32 o NTFS.
- DriveType: Retorna una enumeración (ver el ejemplo) para el tipo de la unidad (Fijo, Optico, Red, etc.)
- IsReady: Retorna el estado de la unidad. Especifica si la unidad esta lista para ser accedida (por ejemplo no es posible acceder a mi unidad de CD mientras escucho mi CD de musica)
- Name: El nombre de la unidad.
- RootDirectory: Retorna un objeto DirectoryInfo que representa el directorio raiz de la unidad.
- TotalFreeSpace: Retorna el total de espacio libre en la unidad (en bytes).
- TotalSize: Retorna el tamaño total de la unidad.
- VolumeLabel: Retorna o escribe una etiqueta para unidades que no sean de solo lectura (CD/DVD).

Veamos un ejemplo utilizando algunos de estos conceptos:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Exam70536.FileSystemTest
{
class Program
{
private const string HARD_DRIVES = "Unidades de Discos duros";
private const string NETWORK_DRIVES = "Unidades de Red";
private const string OPTICAL_DRIVES = "Unidades de CD/DVD";
private const string REMOVABLE_DRIVES = "Unidades Extraibles";
private const string LINE = "--------------------------------------------";

static void Main(string[] args)
{
ViewSystemDrives();
Console.ReadKey();
}

private static void ViewSystemDrives()
{
DriveInfo[] drives = DriveInfo.GetDrives();
List<DriveInfo> hardDrives = null;
List<DriveInfo> opticalDrives = null;
List<DriveInfo> netDrives = null;
List<DriveInfo> remDrives = null;

try
{
hardDrives = new List<DriveInfo>();
opticalDrives = new List<DriveInfo>();
netDrives = new List<DriveInfo>();
remDrives = new List<DriveInfo>();

foreach (DriveInfo drive in drives)
{
switch (drive.DriveType)
{
case DriveType.CDRom:
if (drive.IsReady)
opticalDrives.Add(drive);
break;
case DriveType.Fixed:
hardDrives.Add(drive);
break;
case DriveType.Network:
netDrives.Add(drive);
break;
case DriveType.NoRootDirectory:
break;
case DriveType.Ram:
break;
case DriveType.Removable:
remDrives.Add(drive);
break;
case DriveType.Unknown:
break;
default:
break;
}
}

Console.WriteLine(HARD_DRIVES);
Console.WriteLine(LINE);
foreach (DriveInfo hDrive in hardDrives)
{
Console.WriteLine("{0} Tamaño:{1}GB Espacio disponible:{2}GB",
hDrive.Name,
hDrive.TotalSize / 1024 / 1024 / 1024,
hDrive.AvailableFreeSpace / 1024 / 1024 / 1024);
}

Console.WriteLine();
Console.WriteLine(OPTICAL_DRIVES);
Console.WriteLine(LINE);
foreach (DriveInfo oDrive in opticalDrives)
{
Console.WriteLine("{0}", oDrive.Name);
}

Console.WriteLine();
Console.WriteLine(REMOVABLE_DRIVES);
Console.WriteLine(LINE);
foreach (DriveInfo rDrive in remDrives)
{
Console.WriteLine("{0}", rDrive.Name);
}

Console.WriteLine();
Console.WriteLine(NETWORK_DRIVES);
Console.WriteLine(LINE);
foreach (DriveInfo nDrive in netDrives)
{
Console.WriteLine("{0}", nDrive.Name);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}