Cómo resolver & # 8220; Debe ser MarshalByRefObject & # 8221; en un lenguaje amputado bueno pero de herencia múltiple como C #?

StackOverflow https://stackoverflow.com/questions/313243

Pregunta

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

El problema es muy simple, en varios casos solo tiene que heredar de esta clase (requisitos de infraestructura). Realmente no importa aquí, qué casos. Entonces, ¿qué haces si ya has heredado de otra clase (tus requisitos de modelo de dominio)?

Por cierto, los buenos marcos de aplicación, como spring.net, siempre se aseguran de que NO tenga que heredar de esta clase, sin importar qué tipo de infraestructura necesite aplicar a su clase.

¿Me gustaría saber para qué obtengo -3 votos aquí? :)

¿Fue útil?

Solución

En general, solo desea hacer un objeto MarshalByRef si lo va a usar en un contexto Remoting / WCF. Este suele ser un caso lo suficientemente especial como para que no sea un dolor.

Suponga que tiene un tipo general, y desea derivarlo y especializarlo, y luego alejar el tipo derivado; ahora tiene un problema, porque para ser remoto, un objeto debe heredar de MarshalByRefObject y su tipo general original. no lo hizo Supongamos que no puede cambiarlo porque está haciendo una herencia binaria, o porque se deriva de una clase base que no puede cambiar. Como señala el interrogador, dado que C # (y .NET en general) no permite MI, no puede heredar de ambos.

La respuesta corta es que estás un poco jodido. Puede cambiar el tipo general a inhert de MarshalByRefObject (o ir tan lejos en la cadena que puede insertarlo en algún lugar efectivo), o puede pensar en muckear 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 heredado de MarshalByRefObject que también implemente esa interfaz por composición y delegación a una instancia de su tipo (es decir, un contenedor). Luego, puede usar una instancia remota de ese tipo de proxy que creará una instancia de su tipo y hará el trabajo como se espera, 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();
    }
}

Parece mucho trabajo, sin embargo. En última instancia, si se encuentra en este escenario, sugeriría un rediseño o un replanteamiento.

Otros consejos

Depende de cómo lo necesites. El uso de 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 raro que la herencia múltiple sea la única solución a un problema.

No se puede heredar de varias clases. Por lo tanto, debe (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 sobre por qué necesita heredar de MarshalByRefObject o por qué su clase base no lo hace (¿no?) entonces es difícil dar más consejos concretos.

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

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

¿Puede crear una clase base para la parte de su modelo de dominio que requiera herencia de MarshalByRefObject?

Tuve éxito con un enfoque genérico. T no tiene que ser '' MarshalByRefObject ''. Por supuesto, tendrá que reemplazar " RemoteProcess " con el objeto que usas para la comunicación remota. Entonces 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));
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top