Come risolvere & # 8220; Deve essere MarshalByRefObject & # 8221; in un linguaggio amputato buono ma a eredità multipla come C #?

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

Domanda

Come risolvere " Deve essere MarshalByRefObject " in un linguaggio amputato buono ma a eredità multipla come C #?

Il problema è molto semplice, in molti casi devi solo ereditare da questa classe (requisiti di infrastruttura). Qui non importa davvero, quali casi. Quindi, cosa fai se hai già ereditato da un'altra classe (i requisiti del tuo modello di dominio)?

Tra buoni framework applicativi, come spring.net, assicurati sempre di NON dover ereditare da questa classe, indipendentemente dal tipo di infrastruttura che devi applicare alla tua classe.

Vorrei sapere per cosa ottengo -3 voti qui ?? :)

È stato utile?

Soluzione

In generale, vuoi creare un oggetto MarshalByRef solo se lo utilizzerai in un contesto Remoting / WCF. Questo di solito è un caso abbastanza speciale che non è un dolore.

Supponi di avere un tipo generale e di voler derivarne da esso e specializzarlo, quindi remoto il tipo derivato - ora hai un problema, perché per essere remotato un oggetto deve ereditare da MarshalByRefObject e il tuo tipo generale originale non l'ha fatto. Supponiamo che tu non possa cambiarlo perché stai facendo ereditarietà binaria o perché essa stessa deriva da una classe base che non puoi cambiare? Come sottolinea l'interrogante, poiché C # (e .NET in generale) non consentono l'MI, non è possibile ereditare da entrambi.

La risposta breve è che sei un po 'fregato. O cambi il tipo generale da ereditare da MarshalByRefObject (o vai abbastanza in alto nella catena da poterlo inserire da qualche parte efficace), oppure puoi pensare a confonderti con oggetti proxy.

Ad esempio, è possibile creare un contratto di interfaccia che descriva l'interfaccia del proprio tipo e quindi creare un tipo di proxy che eredita da MarshalByRefObject che implementa anche tale interfaccia per composizione e delega in un'istanza del proprio tipo (ovvero un wrapper). È quindi possibile remotare un'istanza di quel tipo di proxy che creerebbe un'istanza del tipo e farebbe il lavoro come previsto, ma tutti i tipi restituiti dai metodi devono essere [serializzabili].

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();
    }
}

Sembra un sacco di lavoro, però. Alla fine, se ti trovi in ??questo scenario, suggerirei una riprogettazione o un ripensamento.

Altri suggerimenti

Dipende da come è necessario farlo. L'uso di una classe base derivata da MarshalByRefObject potrebbe farlo. L'aggregazione potrebbe farlo. Senza un esempio più concreto di ciò di cui hai bisogno è difficile da dire, ma è raro che l'ereditarietà multipla sia l'unica soluzione a un problema.

Non puoi ereditare da più classi. Quindi è necessario (a) modificare la gerarchia ereditaria in modo che la base erediti da essa o (b) scrivere l'applicazione in modo diverso.

Senza ulteriori informazioni su perché devi ereditare da MarshalByRefObject o perché la tua classe base non lo fa (non è possibile?), allora è difficile dare qualche consiglio più concreto.

Ma direi che se hai un tipo derivato che necessita di diverse semantiche di marshalling alla sua base, allora probabilmente hai un problema di architettura da qualche parte.

" Quindi, cosa fai se hai già ereditato da un'altra classe (i requisiti del tuo modello di dominio)? "

Puoi creare una classe base per il pezzo del tuo modello di dominio che richiede l'ereditarietà da MarshalByRefObject?

Ho avuto successo con un approccio generico. T non deve essere " MarshalByRefObject " ;. Ovviamente dovrai sostituire " RemoteProcess " con l'oggetto che usi per i telecomandi. Quindi puoi accedere al tuo oggetto non MarshalByRefObject come 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));
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top