如何用 C# 等良好但多继承的截断语言解决“必须是 MarshalByRefObject”?
问题很简单,在某些情况下你只需要从这个类继承(基础设施要求)。在这里真的无关紧要,哪种情况。那么,如果您已经从其他一些类(您的领域模型要求)继承,您会怎么做?
顺便说一句,好的应用程序框架,如 spring.net 始终确保您不必从此类继承,无论您需要将哪种基础设施应用于您的类。
我想知道我在这里得到-3票是为了什么?:)
如何用 C# 等良好但多继承的截断语言解决“必须是 MarshalByRefObject”?
问题很简单,在某些情况下你只需要从这个类继承(基础设施要求)。在这里真的无关紧要,哪种情况。那么,如果您已经从其他一些类(您的领域模型要求)继承,您会怎么做?
顺便说一句,好的应用程序框架,如 spring.net 始终确保您不必从此类继承,无论您需要将哪种基础设施应用于您的类。
我想知道我在这里得到-3票是为了什么?:)
一般来说,如果您要在 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();
}
}
不过,看起来工作量很大。最终,如果您处于这种情况下,我建议您重新设计或重新思考。
这取决于您需要如何处理它。使用派生自 MarshalByRefObject 的基类可能会做到这一点。聚合可能会做到这一点。如果没有更具体的示例来说明您需要什么,很难说,但在极少数情况下,多重继承是解决问题的唯一方法。
您不能从多个类继承。因此,您要么需要 (a) 更改继承层次结构,以便基础继承自它,要么 (b) 以不同的方式编写应用程序。
如果没有更多关于为什么需要继承MarshalByRefObject
或为什么基类不需要(不能?)的信息,那么很难给出更具体的建议。
但是我会说,如果您有一个派生类型需要对其基进行不同的编组语义,那么您可能在某个地方遇到了架构问题。
“那么,如果你已经从其他类(你的领域模型要求)继承了,你会怎么做?”
您可以为需要从 MarshalByRefObject 继承的域模型创建一个基类吗?
我采用通用方法取得了成功。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));
}
}