También estaba buscando un patrón para simular la especialización de plantillas. Hay algunos enfoques que pueden funcionar en algunas circunstancias. Sin embargo, ¿qué pasa con el caso?
static void Add<T>(T value1, T value2)
{
}
Sería posible elegir la acción utilizando declaraciones, por ejemplo if (typeof(T) == typeof(int))
. Pero hay una mejor manera de simular la especialización de plantillas reales con la sobrecarga de una sola llamada de función virtual:
public interface IMath<T>
{
T Add(T value1, T value2);
}
public class Math<T> : IMath<T>
{
public static readonly IMath<T> P = Math.P as IMath<T> ?? new Math<T>();
T IMath<T>.Add(T value1, T value2)
{
throw new NotSupportedException();
}
}
class Math : IMath<int>, IMath<double>
{
public static Math P = new Math();
int IMath<int>.Add(int value1, int value2)
{
return value1 + value2;
}
double IMath<double>.Add(double value1, double value2)
{
return value1 + value2;
}
}
Ahora podemos escribir, sin tener que conocer el tipo de antemano:
static T Add<T>(T value1, T value2)
{
return Math<T>.P.Add(value1, value2);
}
private static void Main(string[] args)
{
var result1 = Add(1, 2);
var result2 = Add(1.5, 2.5);
return;
}
Si la especialización no solo debe llamarse para los tipos implementados, sino también para los tipos derivados, se podría usar un In
parámetro para la interfaz. Sin embargo, en este caso, los tipos de retorno de los métodos ya no pueden ser del tipo genérico T
.