Как решить «Должен быть MarshalByRefObject» в хорошем, но с множественным наследованием языке, таком как C #?

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

Вопрос

Как решить " Должен быть MarshalByRefObject " в хорошем, но множественном наследовании ампутированном языке, как C #?

Проблема очень проста, в некоторых случаях вам просто нужно наследовать от этого класса (требования к инфраструктуре). Здесь не имеет значения, в каких случаях. Итак, что вы делаете, если вы уже унаследовали от какого-то другого класса (ваши требования к модели домена)?

Между прочим, хорошие фреймворки приложений, такие как spring.net, всегда гарантируют, что вам НЕ нужно наследовать от этого класса, независимо от того, какую инфраструктуру вам нужно применить к вашему классу.

Я хотел бы знать, за что я получаю -3 голоса здесь ?? :)

Это было полезно?

Решение

В общем случае вы хотите создать объект MarshalByRef только в том случае, если собираетесь использовать его в контексте Remoting / WCF. Обычно это достаточно особый случай, когда это не больно.

Предположим, у вас есть общий тип, и вы хотите извлечь его из него и специализировать его, а затем удалить удаленный тип - теперь у вас есть проблема, потому что для удаленного доступа объект должен наследоваться от MarshalByRefObject и вашего исходного общего типа не сделал. Предположим, вы не можете изменить его, потому что вы делаете двоичное наследование, или потому что оно само происходит от базового класса, который вы не можете изменить? Как указывает спрашивающий, поскольку C # (и .NET в целом) не допускает MI, вы не можете наследовать от обоих.

Короткий ответ: ты как-то облажался. Вы можете либо изменить общий тип на унаследованный от MarshalByRefObject (или пройти достаточно далеко вверх по цепочке, чтобы вставить его где-нибудь эффективно), либо вы можете подумать об использовании прокси-объектов.

Например, вы можете создать интерфейсный контракт, описывающий интерфейс вашего типа, а затем создать прокси-тип, унаследованный от MarshalByRefObject, который также реализует этот интерфейс по составу и делегированию экземпляру вашего типа (т. е. оболочке). Затем вы можете удалить экземпляр этого прокси-типа, который будет создавать экземпляр вашего типа и выполнять работу, как ожидается, но все возвращаемые типы из методов должны быть [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();
    }
}

Похоже, много работы. В конечном счете, если вы находитесь в этом сценарии, я бы предложил изменить дизайн или переосмыслить.

Другие советы

Это зависит от того, как вам это нужно. Использование базового класса, производного от MarshalByRefObject, может сделать это. Агрегация может сделать это. Трудно сказать без более конкретного примера того, что вам нужно, но это редкий случай, когда множественное наследование было бы единственным решением проблемы.

Вы не можете наследовать от нескольких классов. Поэтому вам нужно либо (а) изменить иерархию наследования, чтобы база наследовала ее, либо (б) написать ваше приложение по-другому.

Без дополнительной информации о почему вам нужно наследовать от MarshalByRefObject или почему ваш базовый класс не (не может?), тогда трудно дать более конкретный совет.

Но я бы сказал, что если у вас есть производный тип, который нуждается в другой семантике маршалинга для своей базы, то, возможно, у вас где-то возникла архитектурная проблема.

" Итак, что вы будете делать, если вы уже унаследовали от какого-то другого класса (требования модели вашего домена)? "

Можете ли вы создать базовый класс для части вашей доменной модели, которая требует наследования от MarshalByRefObject?

У меня был успех с общим подходом. T не обязательно должен быть «MarshalByRefObject». Конечно, вам придется заменить " RemoteProcess " с объектом, который вы используете для удаленного взаимодействия. Затем вы можете получить доступ к вашему не MarshalByRefObject как 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));
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top