19

如何用 C# 等良好但多继承的截断语言解决“必须是 MarshalByRefObject”?

问题很简单,在某些情况下你只需要从这个类继承(基础设施要求)。在这里真的无关紧要,哪种情况。那么,如果您已经从其他一些类(您的领域模型要求)继承,您会怎么做?

顺便说一句,好的应用程序框架,如 spring.net 始终确保您不必从此类继承,无论您需要将哪种基础设施应用于您的类。

我想知道我在这里得到-3票是为了什么?:)

4

5 回答 5

18

一般来说,如果您要在 Remoting / WCF 上下文中使用它,您只想创建一个对象 MarshalByRef。这通常是一种足够特殊的情况,它并不痛苦。

假设你有一个通用类型,你想从它派生并专门化它,然后远程派生类型 - 现在你有一个问题,因为要远程一个对象必须从 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();
    }
}

不过,看起来工作量很大。最终,如果您处于这种情况下,我建议您重新设计或重新思考。

于 2008-11-24T02:11:09.837 回答
1

这取决于您需要如何处理它。使用派生自 MarshalByRefObject 的基类可能会做到这一点。聚合可能会做到这一点。如果没有更具体的示例来说明您需要什么,很难说,但在极少数情况下,多重继承是解决问题的唯一方法。

于 2008-11-24T02:10:46.593 回答
1

您不能从多个类继承。因此,您要么需要 (a) 更改继承层次结构,以便基础继承自它,要么 (b) 以不同的方式编写应用程序。

如果没有更多关于为什么需要继承MarshalByRefObject或为什么基类不需要(不能?)的信息,那么很难给出更具体的建议。

但是我会说,如果您有一个派生类型需要对其基进行不同的编组语义,那么您可能在某个地方遇到了架构问题。

于 2008-11-24T02:12:00.223 回答
0

“那么,如果你已经从其他类(你的领域模型要求)继承了,你会怎么做?”

您可以为需要从 MarshalByRefObject 继承的域模型创建一个基类吗?

于 2008-11-24T02:44:20.613 回答
0

我采用通用方法取得了成功。T 不必是“MarshalByRefObject”。当然,您必须将“RemoteProcess”替换为您用于远程处理的对象。然后,您可以作为 RemotingHost.RemoteObject 访问您的非 MarshalByRefObject。

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));
    }
}
于 2014-09-02T15:12:01.297 回答