¿Puedo llamar a un método estático que reside en una clase base con una referencia a la clase que implementa esa clase base (en C#)?
Tengo dificultades para formular la pregunta, lo que también me está haciendo difícil buscar respuestas.
Aquí hay un escenario inventado que imita lo que me gustaría hacer:
“`c#
void Main()
{
Console.WriteLine(TestClassA.NombreDeMiPropiedad());
Console.WriteLine(TestClassB.NombreDeMiPropiedad());
var altavoz = new TestSpeaker();
altavoz.Hablar<TestClassA>();
altavoz.Hablar<TestClassB>();
}
public class TestSpeaker {
public void Hablar<T>() where T : BaseClass<T> {
Console.WriteLine(/* Quiero llamar a T.NombreDeMiPropiedad () aquí */);
}
}
public class TestClassA : BaseClass<TestClassA> {
public string Nombre { get; set; }
}
public class TestClassB : BaseClass<TestClassB> {
public string OtroNombreDePropiedad { get; set; }
}
public abstract class BaseClass<T> {
public static string NombreDeMiPropiedad(){
return typeof(T).GetProperties().Single().Name;
}
}
“`
La Consola actualmente mostraría:
Nombre
OtroNombreDePropiedad
Me gustaría reemplazar mi código comentado para que lea:
Nombre
OtroNombreDePropiedad
Nombre
OtroNombreDePropiedad
davy.ai
La pregunta específica que se está haciendo parece ser cómo llamar al método
MyPropertyName()
para el tipo genéricoT
dentro del métodoSpeak<t>
en el código C# dado.Una posible solución al problema es añadir una restricción a la clase
BaseClass<t>
para que implemente una interfaz con la propiedad deseada (Name
oOtherPropertyName
). Entonces, se debe hacer un casting del objetoT
que se pasa al métodoSpeak<t>
al tipo de la interfaz y llamar la propiedad. Por ejemplo:“`c#
public interface IHasPropertyName {
string PropertyName { get; }
}
public class TestSpeaker {() where T : BaseClass , IHasPropertyName {
public void Speak
Console.WriteLine(((IHasPropertyName)new T()).PropertyName);
}
}
public class TestClassA : BaseClass, IHasPropertyName {
public string Name { get; set; }
}
public class TestClassB : BaseClass, IHasPropertyName {
public string OtherPropertyName { get; set; }
}
public abstract class BaseClass where T : BaseClass {
}
“`
Este código modificado añade la interfaz
IHasPropertyName
, que es implementada porTestClassA
yTestClassB
con sus respectivas propiedades. El métodoSpeak<t>
ahora está restringido para aceptar solo tipos que implementen esta interfaz.Dentro del método
Speak<t>
, el objetoT
es cast a un tipo de interfazIHasPropertyName
, lo que permite acceder directamente a la propiedadPropertyName
sin tener que depender de la reflexión. El método estáticoMyPropertyName()
enBaseClass<t>
ya no necesita ser llamado.