有时,当使用库供应商(如DevExpress )创建的组件时,您希望扩展这些组件。好的供应商将为您留下大量的虚拟方法供您使用,但有时您需要连接到显式实现该方法的类中的接口方法调用。您可以简单地重新实现接口方法,但是10次中有9次您仍然希望调用基本实现,就好像它是虚拟的一样。事实上,CA1033(它应该是虚拟的)。
同时,基本实现是私有的,您需要使用反射。这个类减轻了一些麻烦,这样您就不必提交反射代码了。它为您提供了一个实现接口的对象,该对象直接调用私有的基本实现方法。
一个例子值得一千种解释:
interface IExampleInterface
{
string InterfaceMethod();
}
class BaseClass : IExampleInterface
{
// The authors of BaseClass did not follow CA1033: Interface methods should be callable by child types
string IExampleInterface.InterfaceMethod()
{
return "BaseClass implementation";
}
}
sealed class CustomizedClass : BaseClass, IExampleInterface
{
// We have no choice but to override by implementing the method.
string IExampleInterface.InterfaceMethod()
{
// Now in order to access the base explicit implementation, we use the class below:
return LanguageUtils.ExplicitImplementation<BaseClass, IExampleInterface>(this).InterfaceMethod() + " has been customized.";
}
}
令人惊讶的是,几乎没有任何代码:
public static class LanguageUtils
{
public static TInterface ExplicitImplementation<TBase, TInterface>(TBase @this)
where TBase : TInterface
where TInterface : class
{
return (TInterface)new ExplicitImplementationProxy(typeof(TBase), @this).GetTransparentProxy();
}
private sealed class ExplicitImplementationProxy : RealProxy, IRemotingTypeInfo
{
private readonly Type baseType;
private readonly object instance;
public ExplicitImplementationProxy(Type baseType, object instance) : base(typeof(MarshalByRefObject))
{
this.baseType = baseType;
this.instance = instance;
}
public bool CanCastTo(Type fromType, object o)
{
return fromType.IsInterface && fromType.IsAssignableFrom(baseType);
}
public string TypeName { get; set; }
public override IMessage Invoke(IMessage msg)
{
var methodCall = msg as IMethodCallMessage;
if (methodCall == null) throw new NotSupportedException();
var map = baseType.GetInterfaceMap(methodCall.MethodBase.DeclaringType);
var args = new object[methodCall.Args.Length];
Array.Copy(methodCall.Args, args, args.Length);
return new ReturnMessage(map.TargetMethods[Array.IndexOf(map.InterfaceMethods, (MethodInfo)methodCall.MethodBase)].Invoke(instance, args), args, args.Length, methodCall.LogicalCallContext, methodCall);
}
}
}
发布于 2015-11-05 19:37:32
这是一个相当整洁的实现,这里没什么可说的。一对非常未成年的人:
https://codereview.stackexchange.com/questions/93976
复制相似问题