在上一节中曾经提到,因为 RealProxy 实现上的限制,所有需要被重定向的内部方法,都需要在一个 InternalClass 或 InternalObject 的子类中定义,以满足 MarshalByRefObject 的标记要求。同时这些方法必须以抽象方法方式定义,以便在不提供实现的情况下参与静态类型检查。
以下为引用:
public abstract class VariantClass : InternalClass
public const int CV_I4 = 8;
public static readonly string CLASS_NAME = "System.Variant";
public abstract int GetCVTypeFromClass(Type ctype);
public abstract class VariantObject : InternalObject
public abstract bool IsEmpty { get; }
public abstract uint ToUInt32();
而 Java 的基于接口的代理模型则比这种方式要简洁得多,使用者只需要把希望获得访问能力的方法,放入一个接口中定义好,然后建立代理即可,不受讨厌的 MarshalByRefObject 限制,也可以避免在单根结构的 Java/C# 中的一些额外麻烦。
其实在 CLR 架构中完全可以模拟类似的语义,最终达到如下自动类型转换与封装的效果。无需显式注册内部类和内部对象的封装类,而是直接以接口方式任意定义组合希望访问的内部方法,由代理系统在后台自动完成类型封装和接口转换的工作。
以下为引用:
public interface IWindowsIdentityObject
string[] GetRoles();
IWindowsIdentityObject identity = (IWindowsIdentityObject)WrapperManager.CreateWrapperOfObject(WindowsIdentity.GetCurrent());
foreach(string role in identity.GetRoles())
实现了 IRemotingTypeInfo 接口的真实代理,其创建的透明代理会在进行类型转换时,将转换请求自动转发给 IRemotingTypeInfo.CanCastTo 方法,并根据返回值来模拟真实的转换效果。
实现上,我们只需要让 ClassProxy 和 ObjectProxy 实现 IRemotingTypeInfo 接口,在其中进行是否能够转换的判断即可,最终方法调用会根据名称和参数,在每方法调用一级重新定位。
以下为引用:
internal class ObjectProxy : WrapperProxy, IRemotingTypeInfo, IInternalObject
private readonly ClassProxy _classProxy;
private readonly object _object;
public ObjectProxy(ClassProxy classProxy, Type wrapperClass, object objectToProxy) : base(wrapperClass)
_classProxy = classProxy;
_object = objectToProxy;
#region IRemotingTypeInfo Members
public bool CanCastTo(Type fromType, object o)
return fromType.IsAssignableFrom(_object.GetType()) || _classProxy.CanCastTo(fromType, true);
public string TypeName
return _object.GetType().FullName;
throw new NotSupportedException();
#endregion
如 ObjectProxy 在其 CanCastTo 方法中,首先判断被代理的对象是否直接实现了需转换的接口,如已经实现则直接可以允许转换,具体 Invoke 时自然能够定位到;如果被代理的对象没有实现需转换的接口,则有可能此接口可能是使用者自定义的用于访问内部方法的接口,如前面所定义的 IWindowsIdentityObject 接口。对此类自定义接口,ObjectProxy 不在对象一级进行判断,而是转交给全局唯一用于封装此内部类型的 ClassProxy 处理。
以下为引用:
internal class ClassProxy : WrapperProxy, IRemotingTypeInfo, IInternalClass
#region IRemotingTypeInfo Members
public bool CanCastTo(Type fromType, object o)
return CanCastTo(fromType, false);
public string TypeName
return _classToProxy.FullName;
throw new NotSupportedException();
#endregion
ClassProxy 则在实现 IRemotingTypeInfo.CanCastTo 方法时,直接进行自定义接口的判断,因为在类这个层面,无需支持预定义接口的转换,使用者如果需要可以直接通过 InternalClass.WrappedType 方法获得被包装类型。
因此所有的自定义接口转换判断,实际上都最终落在 ClassProxy.CanCastTo 方法上。此方法将根据需转换接口的所有方法是否都在被封装类型中被实现,来判断是否允许转换到此自定义接口。而通过维护每个内部类型唯一的全局缓存,可以减少这种耗时的冗余检查操作。
以下为引用:
internal class ClassProxy : WrapperProxy, IRemotingTypeInfo, IInternalClass
private IDictionary _clsIntfs= new Hashtable(),
_objIntfs = new Hashtable();
internal bool CanCastTo(Type intf, bool instance)
IDictionary intfs = instance ? _objIntfs : _clsIntfs;
lock(intf)
if(intfs.Contains(intf))
return (Boolean)intfs[intf];
bool canCast = true;
foreach(MethodInfo method in intf.GetMethods())
if(getMethod(_classToProxy, method.Name, instance, getParamTypes(method.GetParameters())) == null)
canCast = false;
break;
intfs[intf] = canCast;
return canCast;
可以看到 ClassProxy 维护了内部类型唯一的 _clsIntfs 和 _objIntfs 两级缓存,分别用于缓存访问类静态方法和普通实例方法的自定义接口,而且凡是进行过转换判断的就缓存起来,以便再次转换时节省工作量。进行检测时,首先会检查缓存中是否保存了对此类型进行转换的信息,如果有则直接返回;否则会对需转换类型的每个方法,检查是否在被代理类型中存在;如果有任意一个方法不存在,则转换会失败;然后此转换的判断结果被保存到相应的缓存中,用于下次转换;最终转换结果被返回给 CLR。
具体转换调用堆栈如下:
以下为引用:
ClassProxy.CanCastTo(System.Type intf = {"NSFocus.Util.Internal.IWindowsIdentityClass"}, bool instance = false)
ClassProxy.CanCastTo(System.Type fromType = {"NSFocus.Util.Internal.IWindowsIdentityClass"}, System.Object o = {System.Runtime.Remoting.Proxies.__TransparentProxy})
public abstract class InternalClass : MarshalByRefObject, IInternalClass
public abstract bool CanCastTo(Type intf);
internal class ClassProxy : WrapperProxy, IRemotingTypeInfo, IInternalClass
public bool CanCastTo(Type intf)
return CanCastTo(intf, base.GetTransparentProxy());
internal interface IInternalObject
bool CanCastTo(Type intf);
public abstract class InternalObject : MarshalByRefObject, IInternalObject
public abstract bool CanCastTo(Type intf);
internal class ObjectProxy : WrapperProxy, IRemotingTypeInfo, IInternalObject
public bool CanCastTo(Type intf)
return CanCastTo(intf, base.GetTransparentProxy());
以下为引用:


public interface IWindowsIdentityClass
{
IntPtr _GetCurrentToken();
}

public interface IWindowsIdentityObject
{
string[] GetRoles();
}

[Test]
public void testAutoBinding()
{
InternalClass clsIdentity = WrapperManager.CreateWrapperOfType(typeof(WindowsIdentity));

Assert.IsTrue(clsIdentity.CanCastTo(typeof(IWindowsIdentityClass)));
Assert.IsFalse(clsIdentity.CanCastTo(typeof(IWindowsIdentityObject)));

Assert.IsNotNull(((IWindowsIdentityClass)clsIdentity)._GetCurrentToken());

InternalObject objIdentity = WrapperManager.CreateWrapperOfObject(WindowsIdentity.GetCurrent());

Assert.IsFalse(objIdentity.CanCastTo(typeof(IWindowsIdentityClass)));
Assert.IsTrue(objIdentity.CanCastTo(typeof(IWindowsIdentityObject)));

Assert.IsTrue(((IIdentity)objIdentity).IsAuthenticated);
Assert.IsTrue(((IWindowsIdentityObject)objIdentity).GetRoles().Length > 0);

try
{
((IWindowsIdentityObject)clsIdentity).GetRoles();;

Assert.Fail();
}
catch(InvalidCastException)
{
}

try
{
((IWindowsIdentityClass)objIdentity)._GetCurrentToken();

Assert.Fail();
}
catch(InvalidCastException)
{
}
}

该文章引用于: http://www.cnblogs.com/flier/archive/2005/02/09/103528.html

在上一节中曾经提到,因为RealProxy实现上的限制,所有需要被重定向的内部方法,都需要在一个InternalClass或InternalObject的子类中定义,以满足MarshalByRefObject的标记要求。同时这些方法必须以抽象方法方式定义,以便在不提供实现的情况下参与静态类型检查。 以下为引用: ... 使用任何穿越远程边界的对象实际上都是在使用 透明 代理 透明 代理 会让你觉得远程对象好像就在客户端空间里。 它会把所有调用通过远程调用框架转发给一个真实对象。 透明 代理 对象寄宿在一个 类型 为RealProxy的托管 类型 实例内,RealProxy实现了转发 透明 代理 传递过来的调用的功能。 获取 透明 代理 定义一个类继承RealProxy, IRemotingTypeInfo...
原因是:proxy.newProxyInstance()中的第二个参数是接口类,那么么传入参数应该是接口.getclass().getinterfeces(),而不是实现类。 能够互相 转换 类型 应该满足继承或者实现,才能够进行强制 转换 proxy的创建中,第二个参数便是接口的所有方法,所以实现了接口,于是可以强制 转换 为接口类。 `uvm_component_utils(class_type_name) `uvm_component_param_utils(class_type_name #(params)) `uvm_object_utils(class_type_name) `uvm_object_param_utils(class_type_name #(params)) 这四个宏中两个是为参数化的类准备的,另外两个是
今天碰到客户的电脑在导出EXCEL的时候提示,无法将 类型 为 excel.applicationclass 的 com 强制 转换 为接口 类型 excel._application 的问题 最后用下面的方法解决,最主要的就是这句话: “C:\Program Files\Microsoft Office\OFFICE11\excel.exe” /regserver  客户电脑的故障是原先导出正常,
以下是解决办法:在主应用(Application)里面加上import mx.managers.DragManager;private var dragManager:DragManager; 转载于:https://www.cnblogs.com/hummersofdie/archive/2010/12/15/1906557.html...
几乎所有java相关框架都需要采用动态 代理 工具; 【个人理解有以下两点】 强 类型 :java是强 类型 语言,在编译阶段有 类型 检测 切面编程:在用户代码执行之前、之后... 织入通用处理逻辑 dubbo提供的动态 代理 工厂有JdkProxyFactory,JavassistProxyFactory 通过ProxyFactory接口的@SPI注解可看到默认实现是JavassistProxyFactory 使用Javassist生成 代理 类文件的核心类有 Proxy, Wrapper
要实现基于 Vue2 的导航栏 透明 渐变,可以按照以下步骤进行: 1. 在组件中引入 `window` 对象,以便在 `mounted()` 钩子中监听 `scroll` 事件。 ```js mounted() { window.addEventListener('scroll', this.handleScroll) 2. 在 `data` 中定义一个变量 `isNavTransparent`,用于判断导航栏是否 透明 。 ```js data() { return { isNavTransparent: true 3. 在 `handleScroll` 方法中根据页面滚动高度来判断导航栏是否需要 透明 渐变。 ```js methods: { handleScroll() { if (window.pageYOffset > 0) { this.isNavTransparent = false } else { this.isNavTransparent = true 4. 在模板中根据 `isNavTransparent` 变量来动态设置导航栏样式。 ```html <template> <nav :class="{ 'is - transparent': isNavTransparent }"></nav> </template> 5. 在样式中定义 `is - transparent` 类,实现导航栏 透明 渐变效果。 ```css nav { position: fixed; top: 0; left: 0; width: 100%; height: 60px; transition: background - color .3s ease - in - out; .is - transparent { background - color: transparent; nav:not(.is - transparent) { background - color: rgba(0, 0, 0, .7); 这样,当用户向下滚动页面时,导航栏就会逐渐变为不 透明 的黑色,当用户向上滚动页面时,导航栏就会逐渐变为 透明