2008-11-24 10 views
15

Cómo resolver "Debe ser MarshalByRefObject" en un lenguaje bueno pero de herencia múltiple amputada como C#?Cómo resolver "Debe ser MarshalByRefObject" en un lenguaje bueno pero de herencia múltiple amputado como C#?

El problema es muy simple, en muchos casos solo tiene que heredar de esta clase (requisitos de infraestructura). No importa aquí realmente, qué casos. Entonces, ¿qué haces si ya has heredado de alguna otra clase (los requisitos de tu modelo de dominio)?

Por cierto, buenos marcos de aplicación, como spring.net, siempre asegúrese de que NO DEBE heredar de esta clase, sin importar qué tipo de infraestructura necesite aplicar a su clase.

Me gustaría saber qué estoy recibiendo -3 votos aquí para ?? :)

+0

Creo que es posible que necesite para proporcionar más contexto sobre lo que el problema real es aquí ... –

+0

1 por lo que Greg dijo que sospecha que su – JaredPar

+0

-3 votos es para el (ahora editado) bromear acerca de un " lenguaje amputado de herencia múltiple ". No todos están de acuerdo en que la herencia múltiple es una buena idea. –

Respuesta

14

En general, solo desea hacer un objeto MarshalByRef si va a utilizarlo en un contexto Remoting/WCF. Por lo general, este es un caso tan especial que no es doloroso.

Supongamos que tiene un tipo general, y quiere derivar de él y especializarlo, y luego remotamente el tipo derivado - ahora tiene un problema, porque para ser remoto un objeto debe heredar de MarshalByRefObject, y su original original tipo no. Supongamos que no puede cambiarlo porque está haciendo herencia binaria, o porque deriva de una clase base que no puede cambiar. Como señala el interlocutor, dado que C# (y .NET en general) no permite MI, no puede heredar de ambos.

La respuesta corta es que estás medio jodido. Cambie el tipo general a inhert desde MarshalByRefObject (o vaya lo suficientemente lejos de la cadena para que pueda insertarlo en algún lugar efectivo), o de lo contrario se le ocurriría rebuscar con objetos proxy.

Podría, por ejemplo, crear un contrato de interfaz que describa la interfaz de su tipo y luego construir un tipo de proxy heredando de MarshalByRefObject que también implemente esa interfaz por composición y delegación a una instancia de su tipo (es decir, un contenedor). A continuación, podría remotamente una instancia de ese tipo de proxy que instanciaría su tipo y haría el trabajo como se esperaba, pero todos los tipos de retorno de los métodos deben ser [Serializable].

public interface IMyType 
{ 
    string SayHello(); 
    string BaseTypeMethodIWantToUse(); 
} 

public class MyType : MyBaseType, IMyType 
{ 
    public string SayHello() 
    { 
     return "Hello!"; 
    } 
} 

public class MyRemoteableType : MarshalByRefObject, IMyType 
{ 
    private MyType _instance = new MyType(); 

    public string SayHello() 
    { 
     return _instance.SayHello(); 
    } 

    public string BaseTypeMethodIWantToUse() 
    { 
     return _instance.BaseTypeMethodIWantToUse(); 
    } 
} 

Aunque parece que hay mucho trabajo. En última instancia, si estás en este escenario, te sugiero un rediseño o un replanteamiento.

+0

@DotNetGuy - gracias por la gran respuesta. – badbadboy

+0

alas, a veces estás atrapado con una aplicación de terceros llena de tipos imposibles de usar :( –

+0

Sí, eso chupa :-) –

1

Depende de cómo lo necesite. Usar una clase base que se deriva de MarshalByRefObject podría hacerlo. La agregación podría hacerlo. Sin un ejemplo más concreto de lo que necesita, es difícil decirlo, pero es un caso raro que la herencia múltiple sea la única solución a un problema.

1

No puede heredar de varias clases. Entonces, o bien necesita (a) cambiar su jerarquía de herencia para que la base herede de ella, o (b) escribir su aplicación de manera diferente.

Sin más información acerca de por qué necesita heredar de MarshalByRefObject o no por las que su clase base hace (no se puede?), Entonces es difícil dar algún consejo más concreto.

Pero yo diría que si tiene un tipo derivado que necesita una semántica de cálculo diferente a su base, entonces probablemente tenga un problema arquitectónico en alguna parte.

+1

La frase "lenguaje de amputación de herencia múltiple" reconoce que el asker entiende que no puede heredar de múltiples clases. –

+0

@ Aaron Palmer: por eso primero voté por Greg, sin embargo, deshice eso cuando agregó más información que en realidad era útil ...así que ahora lo voté :) – badbadboy

+1

En realidad, decir "lenguaje" no reconoce por completo que no es el lenguaje que lo prohíbe, es el .NET Framework, que es algo diferente. Así que sentí que valía la pena aclarar que no es posible tener herencia múltiple en .NET, no solo en C#. –

0

"Entonces, ¿qué haces si ya has heredado de alguna otra clase (los requisitos de tu modelo de dominio)?"

¿Puedes crear una clase base para la pieza de tu modelo de dominio que requiere herencia de MarshalByRefObject?

0

Tuve éxito con un enfoque genérico. T no tiene que ser "MarshalByRefObject". Por supuesto, tendrá que reemplazar "RemoteProcess" con el objeto que utiliza para la comunicación remota. Luego puede acceder a su no-MarshalByRefObject como RemotingHost.RemoteObject.

public class RemotingHost<T> : MarshalByRefObject where T: class 
{ 
    RemoteProcess host; 
    T remoteObject; 
    public T RemoteObject { get { return remoteObject; } } 

    public RemotingAdmin() 
    { 
     host = new RemoteProcess(); 
     remoteObject = (T)host.CreateObject(typeof(T)); 
    } 
}