Son muchas cosas las que se deberían mencionar como para hacer una alusión a cada una de ellas en unas pocas lineas, pero te diré lo que considero que es más importante en general.
1. Usar las declaraciones Option.Activa las declaraciones
Option (excepto
Option Inffer, e ignorando el valor de
Option Compare) por defecto para todos los archivos de los nuevos proyectos, accediendo al menú
Tools -> Options... -> Projects and solutions -> VB DefaultsTambién puedes hacerlo manualmente escribiendo lo siguiente en la cabecera de cualquier clase/módulo, los cambios solamente afectaran a ese archivo:
Option Explicit On
Option Strict On
Option Infer Off
Class ClassName
' ...
End Class
Esto que he mencionado es lo primero que debes hacer, ya que es una medida que conseguirá que adquieras buenas prácticas de programación desde el principio, ya que, entre otras cosas, evitará que puedas escribir y compilar burradas como esta:
Dim form As Object = Nothing
form.Close()
Sin embargo, será algo muy fastidioso si necesitases crear un tipo anónimo como este de abajo, ya que no lo permitirá compilar:
Dim colors = From value In [Enum].GetValues(GetType(ConsoleColor))
Select New With {
.Value = value,
.Name = value.ToString
}
...Pero precisamente este tipo de cosas son las que debes evitar hacer. Siempre puedes rsolver el problema definiendo un Type personalizado:
<Serializable>
Public NotInheritable Class ColorThing
Public Property Name As String
Public Property Value As Integer
End Class
Dim colors As IEnumerable(Of ColorThing) =
From value As ConsoleColor In [Enum].GetValues(GetType(ConsoleColor)).Cast(Of ConsoleColor)()
Select New ColorThing With {
.Value = value,
.Name = value.ToString
}
2. Leer, aprender y practicar las convenciones de código y de nombres.¿Por qué?, pues ...entre otras razones, por que cada lenguaje tiene su estándar, así que al escribir un nombre preciso y del modo correcto estarás ayudando al compiler a identificar el miembro en cuestión, lo que se puede traducir cmo mayor estabilidad y velocidad en general (por ínfima que sea en la mayoría de casos).
Aquí tienes por donde empezar, aunque aquí se menciona solamente una pequeña porción:
➢
Manuales de .NET⇲ Estándares / Adquisición de buenas costumbres Otras convenciones a tener en cuenta:
- Debes ignorar cualquier uso de los miembros contenidos en el namespace Microsoft.VisualBasic (Microsoft.VisualBasic.Left, Microsoft.VisualBasic.Mid, Microsoft.VisualBasic.IsDate y en fin, cualquier nombre de función vista en VisualBasic 6)
- Debes evitar usar prefijos como "_" para declarar variables (tanto en VB.net como en C#), esto es una mala práctica que ha sido adoptada de forma muy común, pongamos como ejemplo esta propiedad con un backing field, la mayoría de personas lo harían así:
Public ReadOnly Property Thing As Boolean
Get
Return Me._thing
End Get
End Property
Private _thing As Boolean = False
Sin embargo, ya he mencionado que el prefijo no se debe usar, así que puedes optar por escribir por ejemplo una "B" al final del nombre, para saber que se trata de un backing field:
Public ReadOnly Property Thing As Boolean
Get
Return Me.thingB
End Get
End Property
Private thingB As Boolean = False
- Debes escribir los nombres de los métodos, funciones, Classes, Modules, Structures, Properties, y muchos más miembros en Word-Casing, y los nombres de las variables generalmente en Camel-Casing, pero se debe tener en cuenta que el estándar de nombre depende de la visibilidad asignada al miembro (public, private, shared, etc), por ejemplo así es como deberías escribir el nombre de una variable en dos casos distintos:
Public MyObject As Object
Private myObject As Object
- Al practicar el P/Invoking (o Platform Invoking), debes comprender que C++ no es C# ni tampoco VB.Net, como ya dije cada lenguaje tiene su estándar de convenciones, y un error muy común en el P/Invoking es copiar o traducir las definiciones de C++ (desde la MSDN o de páginas como www.pinvoke.net) tal y como están escritas para C++, por ejemplo estructuras que llevan nombres completamente en mayúscula, lo que es completamente incorrecto en .Net.
- Utilizar la directiva Using para asegurarte de que un objeto libera sus recursos cuando ya no los necesita, o en su defecto un bloque Try/Catch/Finally
- Asignar siempre un valor de retorno al definir la firma de una función.
- Sustituir a una Class por un Module siempre y cuando sea mejor y óptimo para el compiler, no simplemente para poder usar miembros compartidos/globales.
- Inicializar siempre las variables con un valor por defecto, excepto en casos innnecesarios donde ya se inicializan con un valor por defecto como por ejemplo variables con un datatype Boolean (False) o Integer (0).
- Utilizar el keyword WithEvents al declerar una variable que exponga eventos, y en su lugar omitir el uso de AddHandler/RemoveHandler para usarlos solamente cuando realmente sea necesario.
- Asignarle siempre la firma a un event-handler (un método que controla un evento).
- No hacer uso de ninguna técnica resursiva, es decir evitar cualquier método o función recursiva, ya que inevitablemente la recursividad implica un desborde de la pila (o Stack Overflow).
- No hacer uso del keyword GoTo ni por ende de los labels.
- No utilizar los nombres internos de datatypes como por ejemplo [Int32] en lugar de Integer.
- Muchas cosas más.
3. Aprender a utilizar las características de Visual Studio para detectar y corregir conflictos.Aparte de la depuración con el uso de
break points, la ventana de
Autos, etc,
Visual Studio tiene una herramienta llamada
Code Analysis a la que puedes acceder en el menú
Build -> Run Code Analysis,
como su propio nombre indica, sirve para analizar el código, y al analizarlo detectará y prevendrá posibles conflictos que se te hayan podido pasar por alto, como por ejemplo una fuga de memoria por un objeto sin liberar, un objeto que liberas más de una vez, o cosas tan específicas como un conflicto de portabilización (x86/x64) en una definición de un miembro de la API de Windows.
Es tan imprescindible para desarrollar un buen código como todo lo demás (igual que los tests de unidad), pero lamentablemente pocas personas le sacan provecho a la tan maravillosa IDE que tienen,
Visual Studio.
Nota: Creo que esta herramienta no está disponible en las versiones
Express y
Community de
Visual Studio, pero no estoy seguro. Yo uso
VS2013 Ultimate, y
VS2015 Profesional.
Otra cosa que podrías hacer ...aunque esto personálmente me parece MUY
EXCESIVO excepto para proyectos comerciales, ni yo mismo lo practico generálmente, sería crear tests de unidad (o
Unit Test).
Una unidad consiste en una porción de código, una porción puede ser una variable, un método individual o una class entera.
El test de unidad, digamos que sería una forma automatizada de llevar a cabo diversos análisis para determinar si las funcionalidades de tu código fuente realmente funcionan como es esperado.
Una buenísima herramienta para los tests de unidad es
NCrunch.
4. Utilizar herramientas profesionales para corregir los errores de principiante (y de no tan principiante).Siempre es bueno utilizar una especie de guía, maestro o ayudante en forma de herramienta digital, la cual te vaya indicando los errores que has cometido en tiempo real, y así aprender de ellos para la próxima vez,
mi herramienta o mejor dicho extensión favorita es
Telerik JustCode, aunque hay otras extensiones muy buenas como
ReSharper (exclusivamente para C#).
5. Refactorizar el código.El término Refactorización (o
Refactor) consiste en rediseñar un código/algoritmo para simplificarlo y/o para mejorarlo sin que el código pierda su funcionalidad, principalmente para conseguir hacer lo mismo en menos pasos o para aplicar buenas prácticas de programación a un código "feo", pero simplificar no siempre implica escribir menos.
Esto sería un ejemplo de un código que no ha pasado por la etapa de refactorización:
Dim value1 As Integer = 1
Dim value2 As Integer = 2
Dim value3 As Integer = 3
Dim result As Integer = (value1 + value2 + value3)
MsgBox(value1 & "+" & value2 & "+" & value3 & " = " & result)
El código refactorizado (tener en cuenta que se le podría dar distintos enfoques):
Dim values As IEnumerable(Of Integer) = {1I, 2I, 3I}
MessageBox.Show(String.Format("{0}={1}", String.Join("+", values), Enumerable.Sum(values)))
6. Desarrollar código rehusable.Deberías tratar de transformar un código
hardcodeado en código genérico, rehusable.
(aquí cuidado no confundir el término genérico o
Generics, que tiene un significado distinto en lo que se refiere a los
Types genéricos de un lenguaje de programación)
Es decir, tratar de evitar escribir un código que haga "X" funcionalidad específica solamente para el proyecto que estás desarrollando, la razón es muy sencilla, si en el futuro necesitas volver a desarrollar un código parecido, probablemente lo empezarás desde Cero otra vez, tal vez tomes ese antiguo código como referencia pero igualmente le harás cambios específicos, y eso se traduce en PERDER tiempo.
Ejemplo de un algoritmo sencillo el cual comprueba si una colección contiene un valor específico:
Dim values As String() = {"a", "b", "c", "d", "e"}
Dim exists As Boolean = False
For Each value As String In values
If value.Equals("C", StringComparison.OrdinalIgnoreCase) Then
exists = True
Exit For
End If
Next value
Como se puede comprobar, el código solo sirve para una colección de tipo String, todo está "pre-establecido" para que funcione así.
Ahora, este sería un ejemplo del mismo código o funcionalidad, refactorizada, documentada, genérica, y rehusable:
Dim exists As Boolean = {"a", "b", "c", "d", "e"}.Exists("C", StringComparer.OrdinalIgnoreCase)
#Region " Option Statements "
Option Strict On
Option Explicit On
Option Infer Off
#End Region
#Region " Imports "
Imports System
Imports System.Linq
Imports System.Diagnostics
Imports System.Runtime.CompilerServices
#End Region
''' <summary>
''' Contains custom extension methods applicable to <see cref="IEnumerable(Of T)"/>.
''' </summary>
Public Module EnumerableExtensions
#Region " Public Extension Methods "
''' ------------------------------------------------------------------
''' <summary>
''' Determines whether the specified value exists inside the given collection.
''' </summary>
''' ------------------------------------------------------------------
''' <typeparam name="T"></typeparam>
'''
''' <param name="sender">
''' The collection.
''' </param>
'''
''' <param name="find">
''' The value to find.
''' </param>
''' ------------------------------------------------------------------
''' <returns>
''' <c>true</c> if value exists, <c>false</c> otherwise.
''' </returns>
''' ------------------------------------------------------------------
<Extension>
<DebuggerHidden>
<DebuggerStepThrough>
Public Function Exists(Of T)(ByVal sender As IEnumerable(Of T),
ByVal find As T,
ByVal comparer As IComparer(Of T)) As Boolean
If (sender Is Nothing) Then
Throw New ArgumentNullException(paramName:="sender")
Else
For Each value As T In sender
If comparer.Compare(value, find) = 0 Then
Return True
End If
Next value
Return False
End If
End Function
#End Region
End Module
7. Documentar el código fuente.Ser un programador que documenta su trabajo otorga un mayor nivel de respeto o privilegio por aquello que haces de cara al interés o satisfacción del cliente o de las compañias informáticas, el esfuerzo se ve recompensado,
pero además, una razón igual de importante también, es que documentar te obliga a extender tus habilidades de programación, por que documentar un código en muchas ocasiones implica investigar, leer y aprender sobre aquello que estás llevando a cabo, por ejemplo si haces un copy/paste de un código que no entiendes ...pues así no aprendes nada, pero si intentas documentar ese código que no entiendes, probablemente llegarás a entenderlo de principio a fin con la suficiente dedicación,
por supuesto otra razón no menos importante es que mantener una buena documentación del código ...ya sea usando documentación XML o lineas de comentario, te ayudaría a recordar lo que hace un código que dejaste olvidado años atrás, lo que reduciría el tiempo necesario de refactorización o del tiempo invertido en programar en egeneral.
Se mire por donde se mira, la documentación es una práctica muy buena que te podrá llevar a otro nivel superior de entendimiento (bueno, quizás exagero un poco jaja) si la prácticas constantemente con mucha dedicación por lo que haces.
Hay muchas herramientas de terceros que te ayudarán a aplicar la documentación XML, como por ejemplo:
➢
GhostDoc (tiene una versión gratuita, y realmente no necesitas más)
+
➢
[SOURCE] Snippet Tool Extension For Visual Studio (C#/VB)
Vuelvo a repetir que hay muchas cosas más que se deberían mencionar como por ejemplo realizar
Profillings de rendimiento y memoria, o todo lo que ha comentado el compañero @
El Benjo, pero no se puede hablar sobre todo en un post ...ni en dos.
Creo que con todo esto que mencioné ya es suficiente por hoy, espero que algo de esto le sirva a quien lo lea, por que practicamente (casi) todo lo mencionado es aplicable a
C# también.
Saludos!