首页 文章

为什么这个派生类的行为与它的基类不同

提问于
浏览
7

以某种模糊的方式,一个不添加新功能的派生类(尚未)与它的基类行为不同 . 派生类:

public class MyCheckButton : CheckButton
{
    public MyCheckButton(string label) : base(label)
    {
    }
}

MyCheckButton继承自(GTK#,Mono项目的一部分)CheckButton . 但是,在以下代码段中,它们的行为有所不同:

var button1 = new CheckButton("_foo");
var button2 = new MyCheckButton("_foo");
// code omitted

标签中的下划线确保标签获得助记符 . 对于button1,这适用于我的测试代码:我得到“foo”,其中f加下划线 . 但是对于button2,这会失败 . 我只是在对话框中将“_foo”作为标签 .

任何人都可以解释这个示例中的派生类如何表现不同,或者屏幕后面是否有一些魔法可能会检查实际类的类型?

2 回答

  • 7

    [我]屏幕后面有一些魔法可能会检查实际类的类型?

    实际上,有:

    public CheckButton(string label) : base(IntPtr.Zero)
    {
        if (base.GetType() != typeof(CheckButton))
        {
            ArrayList arrayList = new ArrayList();
            ArrayList arrayList2 = new ArrayList();
            arrayList2.Add("label");
            arrayList.Add(new Value(label));
            this.CreateNativeObject((string[])arrayList2.ToArray(typeof(string)), (Value[])arrayList.ToArray(typeof(Value)));
        }
        else
        {
            IntPtr intPtr = Marshaller.StringToPtrGStrdup(label);
            this.Raw = CheckButton.gtk_check_button_new_with_mnemonic(intPtr);
            Marshaller.Free(intPtr);
        }
    }
    

    看起来你的子类将走向前一条路线 . 不知道为什么那会弄乱助记符;后一种方法是本机gtk库上的P / Invoke . 在 Value 对象中包装 label 可能会破坏助记符 .

    让这成为一个教训(对于GTK#设计师):不要违反Liskov Substitution Principle . 这令人困惑!

  • 2

    这就是原因,看看CheckButton ctor的来源:

    public CheckMenuItem (string label) : base (IntPtr.Zero)
    {
        if (GetType() != typeof (CheckMenuItem)) {
            CreateNativeObject (new string [0], new GLib.Value [0]);
            AccelLabel al = new AccelLabel ("");
            al.TextWithMnemonic = label;
            al.SetAlignment (0.0f, 0.5f);
            Add (al);
            al.AccelWidget = this;
            return;
        }
    
        IntPtr native = GLib.Marshaller.StringToPtrGStrdup (label);
        Raw = gtk_check_menu_item_new_with_mnemonic (native);
        GLib.Marshaller.Free (native);
    }
    

    派生类型与.ctor中的CheckButton不遵循相同的代码路径

相关问题