2010-10-29 10 views
5

Si:de colada permanente a una superclase

class Car : Automobile 
{} 

que puede hacer:

Car toyota = new Car(); 
Automobile tauto = (Automobile)toyota; 

pero si lo hago tauto.GetType().Name todavía será coche.

¿Es posible realizar un molde, de modo que el tipo se cambie permanentemente a Automóvil (sin tener que clonar el objeto)?

El problema que estoy tratando de superar es que no hay herencia múltiple en C#, y necesito fusionar objetos (con la misma firma) de 2 servicios, en un método, y devolver un tipo.

+1

Simplemente curioso: ¿por qué querrías hacer esto? –

+1

Perdón por preguntar, pero ¿por qué querrías hacer eso? El objeto ** es ** un automóvil, no un automóvil. Si quieres un automóvil, ejemplifica uno. – Lazarus

+0

larga historia, pero implica Entity Framework, POCOs, y su incapacidad para usar la misma clase POCO para ser devuelto por 2 conjuntos de entidades diferentes. Así que tengo que sortear eso por herencia ... Pero para el exterior, me gustaría que el objeto de ambas vistas sea el mismo ... así que solo devuelva la súper clase. El lanzamiento simple es problemático porque cosas como el serializador WCF y genéricos .net 3.5 todavía tratan el objeto moldeado como la subclase –

Respuesta

11

No. No hay forma de hacerlo sin construir un nuevo objeto Automóvil.

Sin embargo, tampoco hay ninguna razón para hacer esto. El Liskov substitution principle dice que cualquier Car siempre debe ser tratable exactamente como Automobile, y el usuario no debe tener ningún cambio en el comportamiento esperado.

Siempre que diseñe correctamente su jerarquía de clases, usar Car como Automobile siempre debe ser perfectamente aceptable.


En una nota: Esto es parte de la razón por el uso de Type.GetType() no es la manera preferida para comprobar el tipo. Es mucho más seguro y mejor utilizar las palabras clave is y as en C#. Volverán a ser verdaderos si comprueba que tauto is Car.

+1

lamentablemente wcf serializador se preocupa, y 3.5 genéricos también le importa ... así que no puedo simplemente cambiar ese código ... sé que podría proporcionar mi propia serialización, pero me da muchos dolores de cabeza en todo el lugar ... –

+0

3.5 genéricos no importan - concedido, hay algunos problemas potenciales con la serialización de WCF, aunque eso es raro, y usted debería hacer que tu clase sea serializable de todos modos. Si realmente necesita convertirlo en una subclase, deberá construir un nuevo objeto. Simplemente crea un nuevo constructor en Automobile que sea así: 'public Automobile (Automobile other)', y luego podrás crear eso al pasar a una rutina que realmente te importe ... –

0

Según MSDN, solo está emitiendo la referencia al objeto, y no el objeto subyacente.

0

Su pregunta y lo que intenta hacer parecen dos cosas diferentes. No, no puedes cambiar el tipo subyacente de un objeto. Pero lo que parece querer hacer es crear un tipo de automóvil con un conjunto de propiedades y no usar la subclase. Lo que podrías hacer es usar una fábrica de automóviles en su lugar.

public static class AutomobileFactory() 
{ 
    public static Automobile CreateAutomobile(AutomobileType type) 
    { 
    ... 
    } 
} 

Donde AutomobileType es un enum. Para más información google C# Factory pattern.

0

No estoy seguro de qué es exactamente lo que estás tratando de hacer, pero tal vez podrías considerar un enfoque diferente. En lugar de intentar fusionar la funcionalidad de dos clases diferentes usando herencia, ¿tal vez podrías usar composición?

http://tiedyedfreaks.org/eric/CompositionVsInheritance.html

public class Service 
{ 
    public virtual void DoSomething() 
    { 

    } 
} 

public class ServiceA : Service 
{ 
    public override void DoSomething() 
    { 

    } 
} 

public class ServiceB : Service 
{ 
    public override void DoSomething() 
    { 

    } 
} 

public class ServiceA_B : Service 
{ 
    ServiceA serviceA = new ServiceA(); 
    ServiceB serviceB = new ServiceB(); 

    public override void DoSomething() 
    { 
     serviceA.DoSomething(); 
     serviceB.DoSomething(); 
    } 
} 
0

En algunos casos, los genéricos pueden ayudar. Si un método incluye un parámetro genérico, el tipo genérico se evaluará como el tipo declarado de referencia pasada, en lugar del tipo del objeto transferido. Por ejemplo:

 
void Foo(T bar) 

Si foo() se llama con (Control) someButton, del tipo de 'bar' será Button, pero el tipo de T será de control.

Cuestiones relacionadas