c# - C#如何进行动态绑定(bind)?

标签 c# .net-4.0

我有一个关于 C# 语言的动态绑定(bind)行为的问题。

考虑以下对象层次结构:

object

System.Windows.Forms.Control

ClassA

ClassB

MyClass

中间可能还有其他类,但这些是我们应该考虑的。对象和控件类是 .NET Framework 类。 ClassA 和 ClassB 是第三方库类,MyClass 是......好吧,我的类。
我已经覆盖了 MyClass 中的“Control”TabStop 属性。该属性可能会在层次结构中的其他位置被覆盖,但我认为这并不重要。
(MyClass 位于另一个程序集中,该程序集是一个 vb.net 项目)

Public Overrides Property TabStop As Boolean
    Get
        Return MyBase.TabStop
    End Get
    Set(value As Boolean)
        MyBase.TabStop = value
    End Set
End Property

最后,请考虑以下代码。请注意,myControlCollection 中的某些对象属于 MyClass 类型,其他对象则不是。:

        foreach (Control c in myControlCollection)
        {
            if (c is ClassA)
            {
                if (((ClassA)c).Properties.ReadOnly) c.TabStop = false;
            }
        }

现在问题来了: 我已在 MyClass 的 TabStop 属性的 setter 方法中设置了一个断点。

如果代码按上面给出的方式运行,则集合中的任何对象都不会命中断点。

如果我将行更改为...

((ClassA)c).TabStop = false;

... Visual Studio 在 MyClass 声明中遇到了断点。

这让我很困惑。为什么通过“Control”类型的变量调用该属性时没有命中断点。尽管变量是 Control 类型,但实际对象是 MyClass 类型,所以我相信应该命中断点。
其次,如果通过 Control 类型的变量调用时它没有命中,为什么当我将变量转换为 ClassA 时它会命中。我不是将其转换为 MyClass,而是将其转换为基类,该基类可能有自己的 TabStop 实现,或者可能继承自 Control。无论哪种情况,这都不是我的代码。

有人可以解释一下这种行为吗?

最佳答案

您实际上并未覆盖 TabStop 属性,因为 it is not virtual .

您所做的是通过创建另一个同名的属性来“隐藏”它。因此,当您尝试在此处设置 Control.TabStop 时,会执行不同的属性 setter :

// The static type of c is Control!
if (((ClassA)c).Properties.ReadOnly) c.TabStop = false;

当你在这里设置它时:

// The static type is now ClassA
((ClassA)c).TabStop = false;

当您引用属性时,编译器会使用静态绑定(bind)来解析名称,因为它不是虚拟的。因此,如果您不将该对象转换为比 Control 更派生的对象,您将不会看到自己的代码运行。

更新:这仍然留下一些悬而未决的问题:

  1. 如果变量的静态类型是 ClassA,为什么编译器会绑定(bind)到 MyControl.TabStop?难道它不应该仍然绑定(bind)到 Control.TabStop 吗?
  2. 如果 Control.TabStop 不是虚拟的,为什么编译器允许您编写 Public Overrides Property TabStop As Boolean

我们知道 ControlMyControl 之间的层次结构中必须存在某个类,并且具有虚拟 TabStop 属性(否则 MyControl.TabStop 上的 Overrides 将出现编译器错误)。我们还知道 ClassA.TabStop 最终绑定(bind)到 MyControl.TabStop。假设 ControlClassA 之间的层次结构中没有其他类,则只有一个逻辑解释:类 ClassA 定义了一个虚拟 Shadows Control.TabStop 的 >TabStop 属性。

关于c# - C#如何进行动态绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7358282/

相关文章:

c# - 使用 foreach 枚举内部字典

c# - 将通用属性添加到对象而不必稍后强制转换它们?

c# - 精确/文字单词或模式匹配正则表达式

c# - LINQ 多重排序依据

c# - XAML 绑定(bind)到标签

c# - 如何以编程方式向 log4net 添加过滤器?

string - 使用 StringBuilder 有什么缺点?

.net-4.0 - HtmlString 与 MvcHtmlString

.net - GAC 的位置在哪里?

.net - VB.NET to English - 这行代码应该做什么?