Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
uy
Infocorp
Instructivo
septiembre de 2012 Este documento describe los estndares de codificacin para C# utilizados en el Departamento de Desarrollo.Este documento describe los estndares de codificacin para C# utilizados en el Departamento de Desarrollo.
TABLA DE CONTENIDO
...............................................................................................................................................................................................................1 Tabla de contenido.....................................................................................................................................................................................2 Introduccin................................................................................................................................................................................................3 Objetivo..................................................................................................................................................................................................3 Alcance..................................................................................................................................................................................................3 Condiciones de uso de este documento................................................................................................................................................3 Convenciones utilizadas en este documento.........................................................................................................................................3 Terminologa y definiciones...................................................................................................................................................................4 Fuentes de informacin consultadas.....................................................................................................................................................4 Gua Rpida...............................................................................................................................................................................................5 Convenciones de nomenclatura.............................................................................................................................................................5 Estilos de codificacin............................................................................................................................................................................6 Convenciones de nomenclatura.................................................................................................................................................................8 Guas genricas de nomenclatura.........................................................................................................................................................8 Comentarios y Documentacin Embebida................................................................................................................................................13 Guas para la escritura de comentarios...............................................................................................................................................13 Guas para la escritura de documentacin embebida..........................................................................................................................13 Ciclo de vida de Los objetos.....................................................................................................................................................................14 Guas para la declaracin e inicializacin de variables........................................................................................................................14 Guas para la utilizacin de destructors de clases...............................................................................................................................15 Control de Flujo........................................................................................................................................................................................18 Guas para el uso de variables dentro de sentencias loop...................................................................................................................18 Guas para el uso de sentencias de control.........................................................................................................................................18 Guas para la Programacin de Clases....................................................................................................................................................19 Acerca del uso de propiedades y mtodos..........................................................................................................................................19 Guas para el uso de Propiedades.......................................................................................................................................................20 Guas para el uso de Eventos..............................................................................................................................................................21 Guas para el uso de Mtodos.............................................................................................................................................................23 Guas para el uso de Constructores....................................................................................................................................................26 Guas para el uso de Atributos.............................................................................................................................................................27 Guas para el uso de Parmetros........................................................................................................................................................30 Tipos de Datos.........................................................................................................................................................................................32 Estilo de codificacin................................................................................................................................................................................34 Apndice 1 Tabla de Palabras Reservadas...........................................................................................................................................35
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 2 de 36
INTRODUCCIN
Este documento describe reglas y recomendaciones para el desarrollo de aplicaciones utilizando el lenguaje C# en el Departamento de Desarrollo de Infocorp. La informacin aqu contenida proviene de varias fuentes, las cuales se listan en el Apndice 1: Bibliografa consultada. Especficamente, este documento contiene: Convenciones de nomenclatura Estilo de codificacin Uso del lenguaje Diseo de modelos de objetos.
Objetivo
El principal objetivo de la utilizacin de estndares de codificacin, es institucionalizar buenas prcticas y recomendaciones de diseo, para lograr mayores niveles de calidad en los productos de software desarrollados en el Departamento de Desarrollo. La utilizacin de estndares debe mostrar efectos positivos sobre: Disminucin de errores / bugs, especialmente en aquellos difciles de individualizar. Mantenimiento del cdigo estructurado de acuerdo a las guas de diseo. Mantenimiento del cdigo escrito de acuerdo a un estilo estandarizado. Performance de la aplicacin desarrollada con prcticas eficientes del lenguaje.
Alcance
Este documento aplica nicamente al lenguaje C# y .Net Framework Common Type Systems (CTS). No se incluyen referencias o prcticas relacionadas al uso de las bibliotecas de clases de .Net Framework. Se incluyen algunos comentarios acerca de prcticas comunes y problemas conocidos de C#, las cuales se describen en forma breve. Dado que las prcticas recomendadas en este manual se aplicarn en forma institucional, se han incluido normas que describen el uso de llaves ( {} ) y tabulaciones, para lograr una lectura uniforme del cdigo generado en Infocorp.
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 3 de 36
Descripcin Indica que esta regla DEBE ser respetada, en los trminos de este manual. Indica que esta accin NO DEBE ser realizada, en los trminos de este manual. Indica que esta accin NO DEBE ser realizada, en los trminos de este manual. Indica que esta prctica debe ser evitada siempre que sea posible, pero pueden existir excepciones AUTORIZADAS para su utilizacin. Indica que esta prctica debe aplicarse siempre que sea posible y apropiado. Explica el propsito y las caudas que motivan la regla o recomendacin.
Terminologa y definiciones
Trmino Descripcin Las palabras claves de C# public, protected, internal y private declaran el alcance del acceso que el cdigo permite a sus tipos y miembros. Aunque el acceso por defecto puede variar, las clases y la mayora de los dems miembros del cdigo utilizan private en forma predeterminada. Las excepciones de esta regla incluyen las interfaces y los tipos enumerados, que poseen acceso public en forma predeterminada. Una palabra con la primera letra en minsculas, y la primera letra de cada una de las palabras subsecuentes en maysculas. Ejemplo: customerName Common type System El Common Type System de .Net define cmo deben declararse, utilizarse y administrarse los tipos de datos. Todos los tipos nativos de C# estn basados en el CTS para asegurar la compatibilidad con otros lenguajes del framework. Es un token definido por el programador, que nombra en forma nica un objeto o una instancia de un objeto. Ejemplo: public class MyClassNameIdentifier { }. Cualquier literal numrico utilizado dentro de una expresin (o inicializacin de variable) que no posea un significado claro. Usualmente este trmino no aplica a los valores 0 y 1 y cualquier otra expresin numrica equivalente que su evaluacin resulte 0. Una palabra con la primera letra en maysculas, y la primera letra de cada palabra subsecuente tambin en maysculas. Ejemplo: CustomerName
Access Modifier
Camel Case
Identifier
Magic Number
Pascal Case
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 4 de 36
GUA RPIDA
En esta seccin se incluye un breve resumen de los principales estndares descriptos a los largo de este documento. Estas tablas no son detalladas en sus descripciones, pero brindan una rpida referencia a los elementos.
Convenciones de nomenclatura
c P _ X Camel case Pascal case Prefijo con infraguin (underscore) No aplica
Identificador Archivo de proyecto Archivo del cdigo fuente Otros archivos Namespace Class o Struct
Public P P P P P
Protected X X X X P
Internal X X X X P
Private X X X X P
Notas Debe corresponder al Assembly y al Namespace. Debe corresponder con la clase que contiene. Ver Correspondencia parcial Project / Assembly. Agregar sufijo de la subclase. Ejemplo: AppDomain
Interface
Exception class
Siempre debe tener el sufijo Exception luego del nombre. Ejemplo: AppDomainException
Method
Property
Atributos
_c
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 5 de 36
Identificador
Public
Protected
Internal
Private
P P
P P
P P
_c _c
Enum
P P X X
P P X X
P P X X
Estilos de codificacin
Cdigo Archivo del cdigo fuente (Source code) Llaves {} Tabulacin (Indent) Comentarios (Comments) Variables Tipos de datos nativos (Native Data Types) Enumerados (Enums) Tipos genricos (Generic types) Propiedades (Properties) Mtodos (Methods) Base / This Estilo Un archivo por Namespace y un archivo por clase. Siempre en una nueva lnea. Utilizar parntesis cuando sea opcional. Utilizar siempre tabs de 4 caracteres. No utilizar espacios en blanco. Utilizar //. No utilizar /**/. Una variable por cada declaracin. Priorizar el uso de tipos nativos de C# ante tipos del CTS. Ejemplo: int en lugar de Int32. Evitar cambiar el tipo de dato predeterminado. Utilizar preferiblemente tipos genricos ante tipos estndar o strong-typed classes. No utilizar prefijos Get / Set. Utilizar un mximo de 7parmetros. Utilizar solo en constructors o dentro de override.
Pgina 6 de 36
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Estilo
No modificar tipos enumerados dentro de una sentencia foreach. Evitar la evaluacin de condiciones booleanas contra valores true o false. No realizar asignaciones embebidas. No utilizar invocacin de mtodos embebidos.
No utilizar excepciones para el control de flujo. Utilizar throw; NO throw e; cuando se redirije. Slo utilizar catch cuando es posible manejar la excepcin. Utilizar validaciones para evitar la ocurrencia de excepciones.
Siempre debe validarse el valor null antes de la invocacin. Utilizar lock() en lugar de Monitor.Enter() No utilizar lock en un tipo, por ejemplo: lock(typeof(MyType)); Evitar el uso de lock ante un this, por ejemplo: lock(this); Preferiblemente, utilizar lock en objetos declarados como private, por ejemplo: lock(myVariable);
Utilizarlo siempre que sea possible. Evitar la implementacin de estos mtodos. Utilizar la sintaxis del destructor de C#. Ejemplo: ~MyClass() {} Nunca debe definirse un mtodo llamado Finalize();
AssemblyVersion ComVisibleAttribute
Incrementar en forma manual. Debe estar con el valor false para todos los assemblies.
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 7 de 36
CONVENCIONES DE NOMENCLATURA
La consistencia del cdigo es la clave para su fcil mantenimiento. Esta aseveracin aplica a la nomenclatura utilizada para los nombres de carpetas, archivos y todos los identificadores contenidos en una aplicacin.
REC Utilizar nombres de operaciones aritmticas para nombrar variables que las implementan. Siempre que sea posible es recomendable utilizar los nombres de operaciones aritmticas estndar cuando su resultado se almacene en variables definidas para esos efectos. Ejemplos de estas operaciones son: Sum, Average, Count, Min, Max. En la tabla siguiente se muestran los nombres y abreviaturas sugeridos para identificar estas operaciones. Las abreviaturas son iguales a las utilizadas por MS-Excel. Ejemplo: AverageSalary(long year); CountRows(); REG - Nombrar los namespaces de acuerdo a un pattern bien definido. Los namespaces deben ser nombrados en Pascal, de acuerdo al siguiente pattern: <company>.<technology>.<top-level component>.<bottom-level component> REC Utilizar sustantivos o frases sustantivos para el nombre de clases o struct. Si la clase desarrollada, es una clase derivada, es una buena prctica utilizar un nombre compuesto. Ejemplo: Si tenemos una clase llamada Button, una clase derivada de este podra nombrarse como ShadowButton. REC El nombre de las interfaces debe tener el prefijo I. Todas las interfaces deben comenzar con el prefijo I, y debe utilizarse un sustantivo, una frase con sustantivo o un adjetivo para su nombre. Ejemplo: IComponent sustantivo IComponentAttributePorvider frase con sustantivo IPersistable - adjetivo REC Utilizar nombres similares para la implementacin predeterminada de una interface. Si estamos proveyendo una implementacin predeterminada (default) para una interface particular, se debe utilizar un nombre similar para la clase que la implementa. Nota: Observar que esto aplica slo a las clases que implementan nicamente la interfaz referida. Ejemplo: Si tenemos una clase que implementa la interface IComponent, puede llamarse Component o ComponentDefault. REG Utilizar nombres en singular para tipos enumerados. Para el nombre de los tipos enumerados, debe utilizarse la palabra en singular.
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc Pgina 9 de 36
Ejemplo: Si tenemos un tipo enum en el cual almacenaremos un valor de una coleccin restringida de valores, debe llamarse Protocol y no Protocols. public enum Protocol { Tcp; Udp; http; Ftp: }
REG Utilizar nombres en plural para enumeraciones que representan campos de datos. Ejemplo: [flags] public Enum SearchOptions { CaseInsensitive = 0x01, WholeWordOnly = 0x02, AllDocuments = 0x04, } REC Evitar el uso de las letras I O y los nmeros 1 y 0 juntos. Para generar cdigo ms limpio, es conveniente evitar el uso de las letras I O y los nmeros 1 y 0 juntos, ya que puedan generar una confusin entre nmeros y letras. Ejemplos: Bool b001 = (10 == 10) ? (I1 == 11) : (1O1 != 101); OBL Agregar EventHandler para delegaciones relacionadas a eventos. Las delegaciones que sean utilizadas para definir un event handler para un evento, deben nombrarse agregando el texto EventHandler a su nombre (EventNameEventHandler). Ejemplo: public delegate CloseEventHandler(object sender, EventArgs arguments) OBL Agregar CallBack para delegaciones relacionadas a mtodos callback. Las delegaciones que sean utilizadas para pasar una referencia a un mtodo callback (no a un evento), deben nombrarse agregando el texto CallBack a su nombre (MethodNameCallBack). Ejemplo: public delegate AsyncIOFinishedCallBack(IpcClient client, string message) REC No agregar CallBack a los mtodos callback. No deben utilizarse sufijos CallBack o CB para indicar los mtodos
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 10 de 36
REC Utilizar verbos para nombrar eventos. Utilizar verbos para nombrar los eventos de una clase. Ejemplo: Minimize() Maximize() OBL No agregar el texto Event a los nombres de los eventos. OBL Utilizar sufijos ingy ed para indicar pre-eventos y post-eventos. No utilizar patrones del estilo BeginXXX o EndXXX. Si es necesario proveer diferentes eventos que expresen instancias previas y posteriores en el tiempo, utilizar para su nombre el sufijo ing si indica anterioridad, y el sufijo ed si indica posterioridad. Ejemplo: EntityValidating() Evento pre-validacin EntityValidate() Evento de validacin EntityValidated() Evento post-validacin OBL Agregar el prefijo On para los Event Handlers. Para nombrar los event handlers, debe utilizarse el texto On antepuesto a su nombre. Ejemplo: Si tenemos un mtodo que maneja el evento Close de una clase, debe nombrarse como OnClose(). OBL Nombrar las exception classes utilizando el sufijo Exception. Las exception classes deben nombrarse agregando el texto Exception a su nombre (ClassNameException). Ejemplo: IpcException() OBL No incluir el nombre de la clase dentro del nombre de las propiedades. El nombre de las propiedades no debe incluir el nombre de la clase. Ejemplo: Utilizar Customer.Name No utilizar Customer.CustomerName OBL Nombrar las assemblies DLL luego del namespace que las contiene. Para permitir el almacenamiento de los assemblies en la GAC, sus nombres deben ser nicos. Adems debe utilizarse el nombre del namespace como prefijo del nombre del assembly. Ejemplo: Consideremos un grupo de clases organizadas bajo el namespace Infocorp.ICWorkFlow.Platform.OSInterface. En este caso, el assembly generado por estas clases ser llamado Infocorp.ICWorkFlow.Platform.OSInterface.dll. Si se generan mltiples assemblies desde el mismo namespace, es posible agregar un prefijo nico al nombre del namespace.
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc Pgina 11 de 36
OBL Utilizar notacin Pascal para nombrar los archivos de cdigo fuente. No utilizar infraguiones para nombrar los archivos de cdigo fuente. OBL Nombrar el archivo de cdigo fuente igual a la clase principal que implementa. El archivo de cdigo fuente de una clase, debe tener el mismo nombre que la clase. Adicionalmente no debe incluirse ms de una clase principal por archivo.
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 12 de 36
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 13 de 36
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 14 de 36
} } OBL Implementar IDisposable si una clase utiliza recursos no administrados. Si una clase utiliza recursos no administrados, tales como objetos COM, conexiones, sockets, colas, u objetos que consumen recursos extensamente, stos deben ser liberados tan pronto como sea posible. La implementacin de a interface IDisposable permite a las clases de la aplicacin la liberacin explcita de los recursos no administrados. { ///<summary> ///Implementation of the IDisposable interface ///</summary> public void Dispose() { // Call internal Dispose(bool) Dispose(true); // Prevent the destructor from being called GC.SuppressFinalize(this); } ///<summary> /// Central method for cleaning up resources ///</summary> protected virtual void Dispose4(bool explicit) { // If explicit is true, then this method was called through the // public Dispose() if (explicit) { // Release or cleanup managed resources } // Always release or cleanup (any) unmanaged resources } ~ResourceHolder() { // Since other managed objects are disposed automatically, we // should not try to dispose any managed resources (see Rule 5@114). // We therefore pass false to Dispose() Dispose(false);
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc Pgina 16 de 36
} } Si otra clase deriva de esta clase, la primera slo debe sobre implementar el override del mtodo Dispose(bool) de la clase base. No debe implementar ella misma la interface IDisposable, ni un destructor, pues se dispara automticamente la llamada al destructor de la clase base. { protected override void Dispose(bool explicit) { if (explicit) { // Release or cleanup managed resources of this derived // class only. } // Always release or cleanup (any) unmanaged resources. // Call Dispose on our base class. base.Dispose(explicit); } } OBL Do not access any reference type members in the destructor. Ejemplo: public class DerivedResourceHolder : ResourceHolder
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 17 de 36
CONTROL DE FLUJO
En esta seccin se describen las guas y recomendaciones para la programacin de los procesos de control de flujo y el uso del lenguaje en cada caso.
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 18 de 36
En la siguiente declaracin, Name es una propiedad porque es un miembro lgico de la clase. public string Name get { return name; } set { name = value; }
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 19 de 36
Utilizar un mtodo cuando la obtencin del valor de una propiedad puede tener un efecto colateral observable. Utilizar un mtodo cuando las llamadas sucesivas al miembro de la clase producen resultados diferentes. Utilizar un mtodo cuando el orden de ejecucin es importante Debe considerarse que las propiedades de tipo deben poder asignarse (set) y obtenerse (get) en cualquier orden. Utilizar un mtodo cuando el miembro es esttico, pero retorna un valor que puede ser cambiado. Utilizar un mtodo cuando el miembro retorna un array. Las propiedades que retornan arrays pueden ser difciles de entender, y resultar engaosas. Usualmente es necesario retornar una copia del array interno, pues el usuario no puede cambiar el estado interno. Esta consideracin, asociada al echo que el usuario puede fcilmente asumir que es un propiedad indizada, conduce a que el cdigo sea ineficiente. Ejemplo: En este ejemplo cada llamada a la propiedad Methods crea una copia del array. Como resultado, tendremos 2n+1 copias del array que ser creado en el loop. Type type = // Get a type. for (int i = 0; i < type.Methods.Length; i++) { if (type.Methods[i].Name.Equals ("text")) { // Perform some operation. } } OBL Si un miembro retorna una copia de un tipo de referencia o un array, es obligatoria su documentacin. En forma predeterminada, todos los miembros que necesitan retornar un objeto interno o un array de objetos, retornarn una referencia a este objeto o al array. En estos casos, esta necesidad siempre debe documentarse claramente en la especificacin.
OBL - La asignacin de propiedades debe poder realizarse en cualquier orden. Las propiedades no deben tener estado respecto a otras propiedades de la clase, es decir no debera haber diferencia en el estado del objeto si se asigna primero la propiedad A o la propiedad B. Ms informacin: Property State Issues en [MSDN - Properties usage guidelines] REC - Utilizar mtodos que comuniquen el cambio de una propiedad Los componentes deben disparar eventos que informen el cambio de una propiedad si es necesario notificar a sus clientes cuando se produce un cambio de valor dentro del cdigo. La convencin de nomenclatura para estos eventos, consiste en agregar el sufijo Changed al nombre del evento que implementa la notificacin. Ejemplo: Un campo de testo puede disparar el evento TextChanged cuando su propiedad text cambie de valor. Ms informacin: Raising Property-Changed Events en [MSDN - Properties usage guidelines] OBL - Deben utilizarse propiedades Read-Only cuando el usuario no puede cambiar el valor del miembro lgico de la clase. La implementacin de una propiedad Read-Only se realiza programando slo el mtodo Set de la propiedad. OBL No deben utilizarse propiedades Write-Only. No deben implementarse propiedades que slo contengan el mtodo Get. Index properties.
{ ButtonClickHandler onClickHandler; protected virtual void OnClick(ClickEventArgs e) { // Call the delegate if non-null. if (onClickHandler != null) onClickHandler(this, e); } } OBL Debe asumirse que un event handler puede contener cualquier cdigo. Las clases deben estar preparadas para que los event handler realicen cualquier operacin, y en todos los casos el objeto quede en un estado apropiado luego que el evento sea levantado. Debe considerarse tambin el uso de un bloque try/finally en el punto del cdigo donde se levanta el evento Desde que el programador realiza una function callback sobre el objeto que realize otras acciones, no debe asumirse nada acerca del estado del objeto cuando el control retorna al punto desde donde se levant el evento. { ButtonClickHandler onClickHandler; protected void DoClick() { // Paint button in indented state. PaintDown(); try { // Call event handler. OnClick(); } finally { // Window might be deleted in event handler. if (windowHandle != null) // Paint button in normal state. PaintUp(); } } protected virtual void OnClick(ClickEvent e) { Ejemplo: public class Button
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 22 de 36
if (onClickHandler != null) onClickHandler(this, e); } } REC Utilizar o extender la clase System.ComponentModel.CancelEventArgs Class para permitir al programador controlar los eventos de un objeto. Por ejemplo, el control TreeView control levanta el evento BeforeLabelEdit cuando el usuario edita un nodo del rbol. Ejemplo: Este ejemplo muestra cmo puede utilizarse este mtodo para prevenir la edicin de un nodo. public class Form1: Form { TreeView treeView1 = new TreeView(); void treeView1_BeforeLabelEdit(object source, NodeLabelEditEventArgs e) { e.CancelEdit = true; } } En este caso, el usuario no recibe un mensaje de error, sino que la etiqueta no queda habilitada para su edicin Los eventos Cancel no son apropiados en los casos donde el programador debe cancelar la operacin y devolver una excepcin. En esto casos, debe levantarse la excepcin dentro del event handler. Por ejemplo, el usuario quiz desee incluir cierta lgica de validacin en el control cuando se edita, por ejemplo: public class Form1: Form { EditBox edit1 = new EditBox(); void TextChanging(object source, EventArgs e) { throw new RuntimeException("Invalid edit"); }
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 23 de 36
OBL - Nombrar los Mtodos de acuerdo a las convenciones de nomenclatura indicadas en la seccin [Convenciones de nomenclatura] de este documento. OBL - No utilizar nomenclatura Hngara (hungarian notation). REC - En forma predeterminada, los mtodos no son virtual. Es recomendable mantener esta premisa en todas las situaciones en las cuales no sea expresamente necesario proveer mtodos virtuales. Ms informacin: [MSDN - Base clase usage methods]
REC Uso de overloading. El overloading ocurre cuando una clase contiene dos mtodos con el mismo nombre, pero diferentes signatures. En esta gua incluimos las recomendaciones ms importantes para su uso: Utilizar overloading para proveer diferentes mtodos que hacen semnticamente lo mismo. 1.7. REC - Utilizar overloading en lugar de default arguments. Los argumentos predeterminados (default arguments) no son totalmente compatibles en esta versin del lenguaje y no estn permitidos en el Common Language Specification (CLS). Ejemplo: El siguiente ejemplo muestra el uso del mtodo String.IndexOf con overloading. int String.IndexOf (String name); int String.IndexOf (String name, int startIndex); Los argumentos predeterminados (default arguments) no son totalmente compatibles en esta versin del lenguaje y no estn permitidos en el Common Language Specification (CLS). 1.8. REC - Los valores predeterminados deben utilizarse correctamente. En una familia de mtodos overload, el mtodo complejo debe utilizar nombres de parmetros que indiquen el cambio del estado asumido por defecto en el mtodo simple. Por ejemplo, en el siguiente cdigo, el primer mtodo asume que la bsqueda no es case- sensitive. El segundo mtodo utiliza el nombre ignoreCase en lugar de caseSensitive para indicar como cambia el comportamiento predeterminado. Ejemplo // Method #1: ignoreCase = false. MethodInfo Type.GetMethod(String name); // Method #2: Indicates how the default behavior of method #1 is being // changed. MethodInfo Type.GetMethod (String name, Boolean ignoreCase); 1.9. Utilizar un orden y una nomenclatura consistente para los parmetros. Es comn proveer un conjunto de mtodos overloaded con una cantidad incremental de parmetros para permitir al programador especificar el nivel de informacin que necesite segn las circunstancias. Cuantos ms parmetros se especifiquen, mayor cantidad de opciones poseer el programador. En el siguiente ejemplo, el mtodo Execute est overloaded y posee un orden y una nomenclatura consistente en sus diferentes opciones. Cada variante del mtodo Execute utiliza la misma semntica para el conjunto compartido de parmetros. public class SampleClass {
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc Pgina 24 de 36
readonly string defaultForA = "default value for a"; readonly int defaultForB = "42"; readonly double defaultForC = "68.90"; public void Execute() { Execute(defaultForA, defaultForB, defaultForC); } public void Execute (string a) { Execute(a, defaultForB, defaultForC); } public void Execute (string a, int b) { Execute (a, b, defaultForC); } public void Execute (string a, int b, double c) { Console.WriteLine(a); Console.WriteLine(b); Console.WriteLine(c); Console.WriteLine(); } } Nota: Observar que el nico mtodo en el grupo que debe ser virtual es el que posee la mayor cantidad de parmetros y solo cuando lo que se necesita es extensibilidad. 1.10. REC Si un mtodo debe poseer la posibilidad de ser sobreescrito (override), slo debe implementarse la versin ms completa como virtual, y definir las dems operaciones en funcin de esa implementacin. Ejemplo: public class SampleClass { private string myString; public MyClass(string str) { this.myString = str; } public int IndexOf(string s) { return IndexOf (s, 0);
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 25 de 36
} public int IndexOf(string s, int startIndex) { return IndexOf(s, startIndex, myString.Length - startIndex ); } public virtual int IndexOf(string s, int startIndex, int count) { return myString.IndexOf(s, startIndex, count); } } REC Uso de mtodos con cantidad variable de argumentos Algunas veces es deseable exponer un mtodo que tome una cantidad variable de argumentos. Un ejemplo clsico puede ser el mtodo print de C. Ejemplo: void Format(string formatString, params object [] args) Nota: No debe utilizarse VarArgs o parntesis (), pues la Common Language Specification no lo soporta.
Debe tomarse cuidado si se agrega un constructor no predefinido a una clase en una versin posterior, pues ser eliminado el constructor implcito y esto causar un error en los clientes de esa clase. Por esto mismo, la mejor prctica es proveer siempre explcitamente el constructor de la clase, an cuando sea el predefinido y sea pblico. REC Proveer un constructor protected que pueda ser utilizado por tipos en una clase derivada. REC NO debe proveerse un constructor sin parmetros para un struct. Muchos compiladores no permiten que un tipo struct posea constructor sin parmetros. En este caso, si el programador lo implementa, el runtime inicializa todos los campos del struct en cero. REC Utilizar parmetros en constructors como forma rpida de asignar propiedades. No hay diferencia alguna en invocar primero el constructor y luego asignar las propiedades, o invocar al constructor pasando los valores directamente. Ejemplo: Los tres ejemplos a continuacin son equivalentes: // Example #1. Class SampleClass = new Class(); SampleClass.A = "a"; SampleClass.B = "b"; // Example #2. Class SampleClass = new Class("a"); SampleClass.B = "b"; // Example #3. Class SampleClass = new Class ("a", "b");
public Point(int x, int y) { this.xValue = x; this.yValue = y; } public int X { get { return xValue; } set { xValue = value; } } public int Y { get { return yValue; } set { yValue = value; } } REC - Utilizar una protected property que retorne el valor del atributo para exponerlo a una clase derivada. { private int handle; protected int Handle { get {
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc Pgina 28 de 36
Ejemplo:
return handle; } } } REC - Utilizar atributos public static read-only para instancias predefinidas de los objetos de la clase. Debe utilizarse nomenclatura Pascal, pues los atributos son pblicos. El siguiente ejemplo muestra el uso correcto de los atributos declarados como public static read-only. public struct Color { public static readonly Color Red = new Color(0x0000FF); public static readonly Color Green = new Color(0x00FF00); public static readonly Color Blue = new Color(0xFF0000); public static readonly Color Black = new Color(0x000000); public static readonly Color White = new Color(0xFFFFFF); public Color(int rgb) { // Insert code here.} public Color(byte r, byte g, byte b) { // Insert code here.} public byte RedValue { get { return Color; } } public byte GreenValue { get { return Color; } } public byte BlueValue { get {
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc Pgina 29 de 36
return Color; } } }
throw new ArgumentException( Sys.GetString("InvalidArgument","end",end.ToString())); } } Diferencias entre argumentos pasados por valor o por referencia. Cuando se pasan parmetros por valor, slo se realiza una copia del valor, y por lo tanto no tiene efecto sobre el valor original. Ejemplo: public void Add(object value){} Cuando un parmetro es pasado por referencia, lo que se est transmitiendo es la ubicacin en memoria del valor, por lo tanto el valor original es alterado. Ejemplo: public static int Exchange(ref int location, int value){} Un parmetro de salida (output parameter) representa la misma ubicacin en memoria que la variable especificada encomo argumento en la invocacin del mtodo, como resultado los cambios se realizarn slo en el parmetro de salida. Ejemplo: [DllImport("Kernel32.dll"] public static extern bool QueryPerformanceCounter(out long value)
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 31 de 36
TIPOS DE DATOS
Esta seccin describe el uso de tipos para la definicin de variables y atributos. En esta primera versin slo se describe el uso de los tipos struct y enum. REC Utlizacin de tipos struct Es recomendable la utilizacin de tipos struct cuando el tipo de dato cumple alguno de los siguientes criterios: { public const int MinValue = -2147483648; public const int MaxValue = 2147483647; public static string ToString(int i) { // Insert code here. } public string ToString(string format, IFormatProvider formatProvider) { // Insert code here. } public override string ToString() { // Insert code here. } public static int Parse(string s) { // Insert code here. return 0; } public override int GetHashCode() { // Insert code here. return 0; } public override bool Equals(object obj)
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc Pgina 32 de 36
Acta como un tipo primitivo Tiene un tamao de instancia menor a 16 bytes. Es esttico. Es deseable que los valores conserven una determinada semntica. Ejemplo:
{ // Insert code here. return false; } public int CompareTo(object obj) { // Insert code here. return 0; } } OBL No debe proveerse un constructor para un tipo strct. C# no permite que un tipo struct posea un constructor predeterminado. El runtime inserta un constructor que inicializa todos los valores a estado cero. Esto permite que los arrays de strcts se creen sin necesidad de ejecutar el constructor en cada instancia. REC Recomendaciones para el uso de enums No debe utilizarse el sufijo enum para los tipos definidos como enum. Es recomendable utilizar tipos enum para parmetros, propiedades y valores de retorno que debe ser fuertemente tipados. Siempre deben definirse valores enumerados utilizando enum si son usados en un parmetro o propiedad. Esto permite que las herramientas de desarrollo conocer los posibles valores para las propiedades o parmetros. { Append, Create, CreateNew, Open, OpenOrCreate, Truncate } REC Utilizar tipos enum en lugar de constants estticas No utilizar tipos enum para conjuntos de valores abiertos. Ejemplo: public enum FileMode
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 33 de 36
ESTILO DE CODIFICACIN
Las preferencias en el estilo de codificacin causa generalmente controversias entre los desarrolladores, pues muchas veces se enfrentan preferencias personales. Sin embargo, establecer un estilo uniforme de codificacin dentro de un centro de desarrollo aporta claridad y genera bibliotecas de cdigo entendible y de fcil mantenimiento. Esta seccin describe el estilo de codificacin que se aplica dentro del departamento de Desarrollo de Infocorp, con el objetivo de crear aplicaciones cuyo cdigo sea claro, consistente y fcil de entender por todos los programadores. REC Las secciones public, protected y private de una clase, deben ser declaradas en ese orden. Si bien C# no posee el mismo concepto que C++ en cuanto al acceso a las regiones de cdigo, ser entendido como un estndar la definicin de las secciones en el orden que se indica. Las variables privadas deben ser declaradas al principio de la clase (preferiblemente cerca su propia #region). Las clases anidadas deben definirse al final de la clase. OBL Uso de operadores Esta regla abarca el uso de los siguientes operadores: Unarios: & * + - ! Incrementales y decrementales: -- ++ Llamadas a funciones y operaciones embebidas: () [] Acceso: . No es permitido agregar espacios en blanco entre estos operadores y sus operandos. No es permitido separar los operadores unitarios de sus operandos con una nueva lnea. Ejemplo: a = -- b; // mal a = --c; // bien a = -b c; // bien REC Utilizar Tabs de 4 espacios Esta medida puede personalizarse en Visual Studio. REC No crear lneas de cdigo de ms de 80 caracteres
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 34 de 36
And Base Call CChar CInt CShort Decimal Do End Exit Float GetType Imports Is Loop MustOverride Next Object Overloads Private ReadOnly Resume Shared Stop Then TypeOf While eval
Ansi Boolean Case CDate Class CSng Declare Double Enum ExternalSource For Goto In Let Me MyBase Not On Overridable Property ReDim Return Short String Throw Unicode With extends
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
/var/www/apps/conversion/current/tmp/scratch_5/109933590.doc
Pgina 36 de 36