2008-11-24 27 views
15

如何解决“必须MarshalByRefObject”在一个良好的,但多重继承截断语言,如C#?如何解决“必须MarshalByRefObject”在一个好的,但多重继承截断语言,如C#?

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

顺便说一句好的应用程序框架,比如spring.net,总是确保你不必从这个类继承,不管你需要什么类型的基础设施来适用于你的类。

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

+0

我想你可能需要提供实际的问题是在这里还有什么背景...... – 2008-11-24 01:49:59

+0

+1什么格雷格说 – JaredPar 2008-11-24 01:52:04

+0

我怀疑你-3票是为(现在编辑)妙语关于“多重继承截肢语言“。并非所有人都认同多重继承是一个好主意。 – 2008-11-24 02:10:17

回答

14

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

假设你有一个普通的类型,并且你想从它派生出来并专门化它,然后远程派生类型 - 现在你有一个问题,因为要远程对象必须从MarshalByRefObject继承,而你的原始普通类类型没有。假设你不能改变它,因为你正在做二进制继承,或者因为它本身是从你不能改变的基类派生的?正如提问者指出的那样,由于C#(和.NET一般)不允许MI,所以不能从两者继承。

简短的回答是,你是有点拧。您可以将常规类型从MarshalByRefObject更改为inhert(或者可以将其插入足够长的链中,以便将其插入某个有效的地方),否则您可以考虑使用代理对象。

例如,您可以创建一个描述类型接口的接口契约,然后构建一个继承自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(); 
    } 
} 

虽然似乎很多工作。最终如果你在这种情况下,我会建议重新设计或重新思考。

1

这取决于你如何得到它。使用派生自MarshalByRefObject的基类可以做到这一点。聚合可能会这样做。没有你需要的更具体的例子,很难说,但是多重继承是解决问题的唯一解决方案的情况很少见。

1

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

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

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

0

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

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

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