Espero que esta pregunta no se considere demasiado subjetiva - Realmente no espero una respuesta definitiva, pero espero que la opinión de todos lo haga en menos ayúdame a formar el mío.Sugerencias necesarias: alternativa a la sobrecarga de "es" y "como" operadores en .NET
Estoy implementando un sistema de tipo personalizado, que es un superconjunto del sistema de tipo OOP clásico. En este tipo de sistema, las instancias de objeto se pueden combinar en tiempo de ejecución para formar nuevas instancias, al tiempo que se conservan las identidades individuales.
este código:
var p = new Person();
var pa = new Partner(p);
... resultados en un único objeto combinado, con "p" y "pa" ser diferentes vistas OOP conformes en él. IOW, cambiar el valor de una propiedad en una de las vistas se refleja inmediatamente en cualquier otra vista que también contenga esta propiedad.
Todo esto funciona bien y bien, pero le faltan dos API clave para consultar las identidades de tipo. Realmente me gustaría ser capaz de escribir dicho código:
if (p is Partner)
{
(p as Partner).SomePartnerProperty = "...";
}
Por supuesto, esto no funciona, ya que el comportamiento de "es" y "como" operadores no se pueden sobrecargar/extendió más allá de lo que es .NET Las reglas de OOP dictan. Sin embargo, todavía necesito esta característica en mi sistema de tipos.
Lo primero que pensé fue utilizar métodos de extensión genéricos que uniría a todas las instancias de mi sistema Tipo:
public static bool Is<T>(this BaseType target) where T : BaseType { ... }
public static T As<T>(this BaseType target) where T : BaseType { ... }
Haciendo caso omiso de la cuestión del conflicto de nombres en idiomas mayúsculas y minúsculas, esto parece estar bien en términos de funcionalidad :
if (p.Is<Partner>())
{
p.As<Partner>().SomePartnerProperty = "...";
}
sin embargo, no puede dejar de preguntarse - ¿es realmente el mejor, API más conveniente que uno puede llegar a?
¿Cómo recomendaría implementar estos dos operadores para que se sientan naturales de usar en el código de la aplicación?
ACTUALIZACIÓN: Para cualquier persona que se pregunta acerca de la finalidad de dicho sistema de tipo ... Básicamente, cada tipo cae en una de dos categorías: Identidad o papel. En el ejemplo que di más arriba, Person is an Identity (por diseño), mientras que Partner es un rol (nuevamente, por diseño, podría haber sido diseñado de manera diferente). La regla fundamental de este tipo de sistema es que cualquier número de Roles se puede componer con cualquier Identidad dada, mientras que la Identidad misma solo se puede componer con una Identidad superior (por ejemplo, una Persona puede convertirse en un Contacto, pero nunca puede convertirse en una Compañía). Tal tipo de sistema permite que las aplicaciones traten de forma transparente, por ejemplo, Objetos asociados, independientemente de la identidad que tengan (por ejemplo, persona, empresa, banco, etc.).
Puñalada salvaje aquí, pero me pregunto si podría hacer esto en IronPython más fácil que en C#? Todavía podría escribir un montón de código en C#, simplemente usando IronPython cuando sea necesario. Tal vez alguien conocedor de OO Python pueda sonar. –
¿Podría describirse esto como herencia por instancia (en lugar de por tipo)? Además, ¿qué sucede con el objeto 'p' subyacente cuando aplica valores específicos de' pa'? – Blixt
No debe ignorar los idiomas que no distinguen entre mayúsculas y minúsculas si desea que su biblioteca tenga éxito, pero la buena noticia es que los idiomas insensibles a las mayúsculas y minúsculas (¡al menos VB!) * Pueden * funcionar con dicho código muy bien, aunque 'Is' y 'As' * son * palabras reservadas aquí. El contexto (es decir, como métodos) hace que este uso sea factible. –