domingo, 15 de mayo de 2011

Partial classes en C#

Si estamos escribiendo clases utilizando un generador de código, muchas veces se nos presenta la necesidad de de modificar algunos aspectos de las clases generadas. Si bien es posible modificar el código generado, dicha práctica no es recomendable, ya que cualquier cambio que realicemos sería reemplazado en el momento en que regeneremos el código.

Es ahí donde entra el uso del keyword partial. Cuando definimos una clase como partial (e.g. partial class Test), estamos indicando al compilador de C#, que la definición de la misma se encuentra en múltiples archivos.

Esto nos permite generar el código de nuestra clase en un archivo (e.g. Test.g.cs) y permitir al usuario agregar métodos, propiedades o campos en otro archivo (e.g. Test.cs). De esta manera, cuando el generador cambie, o cuando cambiemos algún parámetro de generación, la parte que fue personalizada por el usuario de nuestro generador permanece incambiada.

Veamos un ejemplo sencillo. Generaremos clases con una propiedad con el mismo nombre de la clase y el sufijo ‘Member’ usando T4 (Text Template Transformation Toolkit) disponible en Visual Studio 2008

[Test.g.tt:]

<#@ template language="C#" #>
<#
string[] names = { "Class1", "Class2" };
foreach(string name in names) {
#>
public partial class <#=name#>
{
public int <#=name#>Member { get;set; }
}
<#
}
#>

Si todo fue bien, debajo de Test.g.tt deberíamos tener un archivo llamado Test.g.cs.

[Test.g.cs:]

public partial class Class1
{
public int Class1Member { get;set; }
}
public partial class Class2
{
public int Class2Member { get;set; }
}

Ahora supongamos que queremos que la clase Class1 tenga un miembro llamado NewMember. Podemos crear un archivo llamado Class1.cs.

[Class1.cs:]

partial class Class1
{
public string NewMember { get;set; }
}

Con esto, Class1 tiene ahora dos miembros y Class2 tiene uno solo. Si cambiamos Test.g.tt, el archivo Test.g.cs será reemplazado, pero nuestro código existente en Class1.cs no se verá afectado.