- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写一段处理 Windows 窗体控件的 C# 代码。这是一个小例子,一个用于获取某些控件的边界矩形(在屏幕坐标中)的小包装器:
public class GUIObject {
protected Control m_control;
// [..]
public virtual Rectangle Bounds {
get {
Rectangle r = m_control.Bounds;
if ( m_control.Parent != null ) {
return m_control.Parent.RectangleToScreen( r );
}
return r;
}
}
}
此代码被编译成一个库,该库作为“插件”分发以加载到客户应用程序中。然而,事实证明,一些客户在他们的应用程序中使用了与我的插件所链接的版本不同的 Windows 窗体版本。我的计划是通过将上述代码后期绑定(bind)来解决这个问题,这样它就可以与当前应用程序域中加载的任何 Windows 窗体版本一起工作。对于 .NET 4,我可以使用 dynamic
关键字,但是遗憾的是,这段代码也应该适用于 .NET3 应用程序。因此,我开始使用反射 API,引入了一个小帮助对象,它使反射 API 的使用变得更好:
public class LateBoundObject {
private Object m_o;
// [..]
public Object GetProperty( String name ) {
PropertyInfo pi = m_o.GetType().GetProperty( name );
return pi == null ? null
: pi.GetValue( m_o, null );
}
public Object InvokeMethod( String name, Object[] args ) {
MethodInfo mi = m_o.GetType().GetMethod( name );
return mi == null ? null
: mi.Invoke( m_o, args );
}
}
public class GUIObject {
protected LateBoundObject m_control;
// [..]
public virtual Rectangle Bounds {
get {
Object r = m_control.GetProperty( "Bounds" );
if ( r == null) {
return new Rectangle();
}
Object parent = m_control.GetProperty( "Parent" );
if ( parent != null ) {
LateBoundObject po = new LateBoundObject( parent );
r = po.InvokeMethod( "RectangleToScreen",
new Object[] { r } );
}
return (Rectangle)r;
}
}
}
不是很漂亮。调用方需要进行大量转换,我怀疑我迟早也必须处理重载的方法或属性——前面的路途很坎坷。理想情况下,包装器对象将允许保持原始代码非常相同。
因此,在我开始修复 LateBoundObject
包装器类之前,我想知道:其他人是否有使用反射 API 使 C# 代码后期绑定(bind)的经验?如果是这样,您是如何处理它以将使用原始反射 API 的痛苦降到最低 - 您是否还使用了 LateBoundObject
的包装类,或者您是否采用了完全不同的路线?就原始代码而言,我正在寻找侵入性最小的方法。
最佳答案
一个想法是为您希望对象的外观创建接口(interface),然后使用 System.Reflection.Emit 生成可以强制转换实际实例的类。您可以通过将其包装在一个动态生成的对象中来实现这一点,该对象代理从其接口(interface)方法到它包装的实际实例的调用。
用法看起来像这样:
interface IGUIObject
{
Rectangle Bounds { get; }
Rectangle RectangleToScreen(Rectangle bounds);
IGUIObject Parent { get; }
}
var obj = GetInstance();
var proxy = Reflection.Coerce<IGUIObject>(obj);
return proxy.Parent.RectangleToScreen(proxy.Bounds);
我在这里有一篇博文,其中包含如何进行动态强制转换的简单起点,包括示例应用程序:coercing types and unloading assemblies
有趣的是,使用这种技术,您实际上可以摆脱每次调用反射,这在性能方面非常昂贵。相反,你在代理生成器中进行一次反射,然后你生成的实际上直接调用相应的属性/方法/字段。同样通过这个技巧,当您删除对代理实例的引用时,生成的动态程序集将被卸载。您可以缓存类型生成的类型,以非常快速地创建后续代理。
你的情况比我的小样本更复杂,但我认为你可以以它为起点走得很远。
关于c# - 在 .NET < 4 中使 C# 代码后期绑定(bind)的侵入性最小的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9670466/
总结 我需要在 Camel 服务器 in-modify-out 过程中构建一组统计数据,并将这些统计数据作为一个对象(单个 json 日志行)发出。这些统计数据需要包括: input file met
某个元素使用以下 CSS 功能产生了惊人的结果: 盒子阴影;边界半径;边框和背景上的 RGBA 颜色。 问题是前两个需要延迟 Firefox/Chrome/Safari 浏览器,第二个不兼容 IE8
在我的 Rails 应用程序中有这段代码: window.onload = -> $("#mycontainer").typewriter() $("#div1").fadeIn("slow"
我想检查我的 api 是否工作正常。我有一个只有 post 请求而没有 GET 的 api。 教程在这里:https://learn.microsoft.com/en-us/azure/applica
我想检查我的 api 是否工作正常。我有一个只有 post 请求而没有 GET 的 api。 教程在这里:https://learn.microsoft.com/en-us/azure/applica
我是一名优秀的程序员,十分优秀!