Overriding Methods in C#

In addition to producing a new class based on an old one by adding additional features, you can modify existing behavior of the parent class.

If a method is defined in a derived class so that the name, return type, and argument list match exactly those of a method in the parent class, then the new method is said to override the old one.

The keyword virtual

In C#, a class can declare virtual methods, properties, and indexers, and derived classes can override the implementation of these function members.

The keyword virtual allows programmers to specify methods that a derived class can override, C# methods are non-virtual by default and must be explicitly declared as virtual.

The implementation of a non-virtual method is invariant: The implementation is the same whether the method is invoked on an instance of the class in which it is declared or an instance of derived class. In contrast, the implementation of a virtual method can be changed by derived classes.

The keyword override

To override a base-class method definition, a derived class must specify that the derived-class method overrides the base-class method with keyword override in the method header.

If the override modifier is not used, the new member hides the inherited member, and a compiler warning occurs. If a derived class attempts to override a non-virtual inherited member, a compiler error will occur.
The following examples illustrate the using of virtual and override keywords.

Fig 1. Class diagram for Employee and Manager using Inheritance.

Listing 1: Sample code for Employee class

Listing 2: Sample code for Manager class

Consider these sample methods in the Employee and Manager classes:
Fig 2. The GetDetails method of the Employee class.

Fig 3. The GetDetails method of the Manager class.

The Manager class has a GetDetails method by definition because it inherits one from the Employee class. However, the original method has been replaced, or overridden, by the derived class’s version.

Listing 3 A simple program to demonstrate how method overriding works.

Fig 4 The output of executing this program is the following.

Download the source code.

Understanding abstract classes with C#

The C# programming language enables a class designer to specify that a base class declares a method that does not supply an implementation. This is called an abstract method. The implementation of this method is supplied by the derived classes. Any class with one or more abstract method is called an abstract class.

Fig 1 UML model of the abstract class.

The purpose of an abstract class is primarily to provide an appropriate base class from which other classes can inherit and thus share a common design.
However, abstract classes can have data attributes, concrete methods, and constructors. For example, the Vehicle class might include load and maxLoad attributes and a constructor to initialize them.
Not all inheritance hierarchies contain abstract classes. However, programmers often write client code that uses only abstract base class types to reduce the client code’s dependencies on a range of specific derived class types.
The C# compiler always prevents you form instantiating an abstract class, for example the following statement is illegal.

 Vehicle v = new Vehicle(); // this is illegal and the compiler generates an error.

Although we cannot instantiate objects of abstract base classes, we will see that we can use abstract base classes to declare variables that can hold references to objects of any concrete classes derived from those abstract classes.

The employee abstract class: A example using Polymorphism through inheritance

What is polymorphism?

The term polymorphism refers to the ability of two or more objects belonging to different classes to respond to exactly the same message (method call) in different class-specific ways, thus polymorphism enables us to “program in the general” rather than “program in the specific”.

Polymorphism allows:

  • Different behavoirs from the same type.
  • Runtime polymorphism is done via overriding.
  • Compile time polymorphism is done via method overloading.
  • Invoke methods of a derived class through a base class.

I think the best way to learn about this concept is through an example, so I wrote a set of examples using an inheritance hierarchy containing types of employees in a company.

Fig 2 Employee hierarchy UML class diagram.

We use abstract class Employee to represent the general concept of an employee. The classes that inherit from Employee are: CommissionEmployee, PieceEmployee and HourlyEmployee.

1. I use abstract class Employee to represent the general concept of an employee. The classes that inherit from Employee are: CommissionEmployee, PieceEmployee and HourlyEmployee.

Listing 1. Abstract base class Employee

In this example, class Employee will provide two methods Earnings and Details, and properties that manipulate an Employee’s instance variables, the method Earnings certainly applies generally to all employee’s, but each earnings calculation depends on the derived employee’s class. So these two methods must be abstract in the Employee class because an implementation does not make sense there, so each derived class must override those methods with an appropriate implementation.

2. I wrote three concrete classes: HourlyWorker, CommissionWorker and PieceWorker. Such classes provide implementations of the abstracts methods declared in our abstract class, because abstract base classes are too general to create real objects.

Listing 2. Concrete derived class HourlyEmployee

Listing 3. Concrete derived class CommissionEmployee

Listing 4. Concrete derived class PieceWorker

To test our example, the following program creates an array of our abstract base class Employee, then assigns the four instances of our concretes classes to the array variable. Finally, the program iterates through array Employee and polymorphically invokes methods Earnings and Details to display the output of each of these methods.

Listing 5. Test program for our example.

Fig 3. The output for our example.

Note: Those examples were based on the examples included in: Deitel’s developer series C# 2010 for programmers.

Download the source code.

Understanding Bitwise Logical Operators with C#

Bit manipulation operations, including logical and shift operations, perform low-level operations directly on the binary representations used in integers. The ability to operate directly on binary might save large amounts of memory, might enable certain computations to be performed very efficiently, and can greatly simplify operations on collections of bits, such as data read form or written to parallel I/O ports.

The C# programming language supports bitwise operations on both numeric and boolean data types. These are represented as the operators ~, &, ^, and | for the bitwise operations of NOT (bitwise complement), bitwise AND, bitwise XOR, and bitwise OR, respectively.
The operators work in parallel on all bits of the operands and never cause overflow, even in a checked context.

Unsigned integers are normally used with the bitwise operators.

Bitwise NOT (complement)

The bitwise complement or NOT is used to flip the bits of a value, this operator is unary and inverts the bit value. Since this operator is a unary operator it cannot be combined with the = sign.

Fig 1 Example of bitwise NOT operator

Bitwise XOR

When combining two values with the logical XOR bitwise operator, you get the following result: if both bits are the same, the result is 0 else if 1 bit is 0 and the other is 1, the result is 1

Fig 2 Example of bitwise XOR Operator

Bitwise OR

When combining 2 byte values results in the following: if both bits are 0, the result is 0. If either or both bits are 1, the result is 1.

Fig 3 Example of bitwise OR operator

Bitwise AND

The bitwise AND operator produces a one in the output bit if both input bits are one; otherwise it produces a zero.

Fig 4 Example of bitwise AND operator

When using the bitwise operator, it’s useful to display values in binary to show the precise effects of these operators.
The following example demonstrate the use of the bitwise operators, it uses the method PrintBits (implemented in class Util) to print the unsigned int values.

The full sample is shown below:

Listing 1 Source code for Util class

Listing 2 Source code for the main program class

Fig 5 Running the sample

Fig 6 Output of the complete example

Download source code

Algoritmo Genético para el TSP (Traveling Salesman Problem) con Monodevelop utilizando C#

La computación evolutiva es una parte de la inteligencia artificial donde se agrupan diferentes técnicas adaptativas enfocadas a encontrar las mejores soluciones para resolver problemas de optimización, estas técnicas parten de una de las principales ideas que existen en la teoría de la evolución biológica propuesta por Charles Darwin, la selección natural es el proceso histórico de transformación de unas especies en otras especies descendientes e incluye la extinción de la gran mayoría de las especies que han existido, lo que es sin duda un problema de optimización además de que muchos de los términos que utiliza la computación evolutiva son tomados de la biología, con la advertencia de que se son usados para representar más o menos la misma idea biológica lo que no equivale a que sean iguales.

La computación evolutiva se compone por las siguientes técnicas:

  1. Programación evolutiva: Son una estrategia de optimización estocástica hacen un énfasis específico en los operadores genéticos tal y como se observan en la naturaleza.
  2. Estrategias evolutivas: Esta técnica esta básicamente enfocada hacia la optimización. En esencia son métodos estocásticos con paso adaptativo, que permiten resolver problemas. A este método se le han agregado procedimientos propios de la computación evolutiva, que lo han convertido en un paradigma más de dicha metodología.
  3. Algoritmos genéticos: Usan métodos que tienen analogía en la selección natural y la evolución.

Entre los usos de la computación evolutiva se encuentran la planificación, el diseño de sistemas, la simulación, el reconocimiento de patrones, el control y la clasificación de datos.

La alternativa para una solución de problemas de planificación y de optimización donde la mayoría están se ubican dentro de la categoría de los problemas NP los cuales no pueden ser resueltos usando las técnicas convencionales y solo pueden ser atacados desde las técnicas de computación evolutiva donde el dominio de esos problemas le corresponden a los algoritmos genéticos (John H. Holland, 1975) 

Como ejemplo de este tipo de aplicaciones me encontré en este web site (http://www.heatonresearch.com) un Applet Java, que utiliza algoritmos genéticos para obtener una solución optima al problema del agente viajero (Traveling Salesman Problem), en el mismo web site el autor nos hace un resumen del problema.

Pues bien como un ejercicio de aprendizaje, traduje el código del applet de Java a C# como un proyecto de Monodevelop utilizando Winforms, a continuación algunas screenshots y el código fuente del proyecto. He de aclarar que debido a la falta de tiempo hice casi copia tal cuál del código, modificando las partes de Java que el compilador me marcaba como errores.

Inicio de la aplicación

Aplicación en ejecucción

Resultado de la aplicación

En su web site el autor Jeff Heaton además del código fuente del applet, ofrece libros acerca de inteligencia artificial y de programación con Java y C#.

Descarga el código fuente en un proyecto para MonoDevelop o Visual Studio

Utilizando secuencias (sequences) en PostgreSQL con C# .

Con frecuencia en un buen diseño de bases de datos es necesario que las tablas tengan al menos un identificador único para poderlas relacionar con otras, siguiendo las recomendaciones de las conocidas reglas de Codd para el modelo relacional de bases de datos.Para cumplir con este requerimiento podemos fijarnos en la entidad que representa cada tabla y seguir la especificación del identificador único que le correspondería según nos dicten las reglas del negocio o el tipo de sistema que vamos a construir.

Hay casos en donde la tabla no tiene una entidad definida sino sirve únicamente como tabla de soporte para una relación muchos a muchos, como un catálogo o un listado de parámetros para el sistema, en estos casos donde no se tiene una especificación definida para asignar un identificador único lo más recomendado es utilizar una serie o un contador como valor para ese identificador.

PostgreSQL proporciona unos objetos llamados secuencias (sequences) que sirven para crear contadores o series, las secuencias son objetos de bases de datos al mismo nivel que las tablas, vistas, triggers o funciones.

Aunque pueden crearse contadores y series de forma manual esto no será tan eficiente como los objetos sequence que nos proporciona PostgreSQL ya que mejoran el desempeño de la base de datos sobretodo en sistemas multiusuario. La forma automática de crear una secuencia es utilizar el tipo de dato serial en una columna, como se muestra a continuación con el siguiente script para una tabla llamada Publishers.

Al ejecutar este script se crean dos objetos: la secuencia (sequence) y la tabla (en ese orden), como lo muestra la pestaña messages de pgadmin al finalizar la ejecución del script.

Ahora creamos una función plpgsql con la que agregaremos los registros a la tabla, en esta función establecemos los valores mediante parámetros para cada una de las columnas, excepto claro el identificador (columna publisherid), ya que de ese valor se encargará la secuencia.

Ahora con el siguiente programa en C# probaremos la secuencia agregando algunos registros e imprimiendo sus identificadores en la consola.

Compilamos el programa con el siguiente comando.

$ gmcs -r:/home/martin/lib/Npgsql2.0.11.94/Mono2.0/bin/Npgsql.dll,System.Data Main.cs

Al ejecutar el programa, se mostrarán los registros agregados y los valores que les asigno la secuencia como identificador.

También podemos crear una secuencia (sequence) de forma manual siguiendo la sintaxis:

create sequence [name] start with [number] increment by [number]

De manera predeterminada las secuencias comienzan en el número 1 al menos no se indique con el comando start with.
Por ejemplo creamos una secuencia que se incremente de 6 en 6

Test=# CREATE SEQUENCE my_first_sequence_seq INCREMENT BY 6;

Para acceder a los valores de la secuencia lo hacemos con un SELECT y la función nextval() como se muestra a continuación:

Observamos que la secuencia comienza en 1 e incrementa de 6 en 6.
Para acceder al valor actual de la secuencia lo hacemos con la función currval() como se muestra a continuación:

Para establecer un nuevo valor en la secuencia utilizamos la función setval()

Por último podemos eliminar la secuencia creada con el comando:


Como se muestra a continuación, en la siguiente imagen:

Descargar el código fuente del ejemplo (Download the source code)

Utilizando parameterized commands (comandos con parámetros) de ADO.NET en PostgreSQL con GTK#

Para complementar el tema del post anterior, como un segundo ejemplo mostramos un formulario GTK# que utiliza una función PL/SQL, en donde además de los parámetros de entrada se establecen dos parámetros de salida, los cuales una vez de ejecutada la función devuelve los valores número de referencia y la fecha actual, que el formulario GTK# muestra en un mensaje.
Para preparar el ejemplo, creamos una base de datos llamada Test con una tabla llamada workitems en donde la función creará un nuevo registro.
Aquí el código de la tabla:

A continuación el código de la función.

Esta función utiliza la función createrefnum(id) utilizada en la primera parte de este tutorial.
En esta función los parámetros de salida se especifican con la palabra reservada OUT junto a los parámetros de entrada en los argumentos, inmediatamente después del la declaración del nombre, como se muestra el siguiente fragmento del código.

create or replace function usp_createworkitem(out nref varchar,varchar,varchar,varchar,
varchar,out creationDate timestamp)

En este ejemplo debemos de tener una solución en MonoDevelop con dos tipos de proyectos: uno de tipo library en donde se pondrán las siguientes clases:
WorkItem.cs : representa la clase de transporte de datos o POCO.
MessageDAC.cs: que representa la clase de acceso a PostgreSQL.

El otro es un proyecto tipo GTK# que contiene las clases Main.cs y MainWindow.cs correspondientes a la GUI del formulario y al manejo de eventos.
La solución deberá de verse como en la siguiente imagen:

El diseño del formulario queda como en la siguiente imagen:

A continuación el código de las clases de la solución.
Aquí el código de las clase Workitem.cs

Aquí el código de la clase MessageDAC.cs

Aquí el código de la clase MainWindow.cs

En la clase MessageDAC se encuentra el código en donde ejecutamos la función, para que se ejecute correctamente debemos establecer la propiedad CommandType de la clase NpgsqlCommand con el valor de la enumeración CommandType.StoredProcedure.

cmd.CommandType = CommandType.StoredProcedure;

Entonces creamos los parámetros de entrada y de salida, para los de salida se crea un NpgsqlParameter por cada uno y se establece su propiedad Direction con la enumeración ParameterDirection.Output, es importante no olvidar agregarlos a la enumeración Parameters del NpgsqlCommand.

NpgsqlParameter nref = new NpgsqlParameter("nref",NpgsqlDbType.Varchar);
nref.Direction = ParameterDirection.Output;
cmd.Parameters.Add("Title",NpgsqlDbType.Varchar).Value = wk.Title;
cmd.Parameters.Add("AssignedTo",NpgsqlDbType.Varchar).Value = wk.AssignedTo;
cmd.Parameters.Add("Area",NpgsqlDbType.Varchar).Value = wk.Area;
cmd.Parameters.Add("Reason",NpgsqlDbType.Varchar).Value = wk.Reason;
NpgsqlParameter created = new NpgsqlParameter("creationDate",NpgsqlDbType.Timestamp);
created.Direction = ParameterDirection.Output;

Después de ejecutar el comando para llamar la función obtenemos el valor de regreso, haciendo referencia por su nombre de la enumeración Parameters.

wk.Numref = cmd.Parameters["nref"].Value.ToString();
wk.Created = Convert.ToDateTime(cmd.Parameters["creationDate"].Value);

Al compilar y ejecutar el formulario se verá como en la siguiente imagen:

Al introducir los valores y presionar el botón OK se ejecutará el llamado a la función agregando el registro y devolviendo los valores de salida, que se mostrarán con un mensaje como se ve en la siguiente imagen:

Si todo se ejecuto correctamente, podemos consultar el registro ejecutando el siguiente comando desde una terminal:

$ psql Test –c “Select * from workitems” - A

Descarga el código fuente en un proyecto para MonoDevelop o Visual Studio