C# 为什么这个派生类的行为与它不同';s基类

C# 为什么这个派生类的行为与它不同';s基类,c#,inheritance,mono,gtk#,C#,Inheritance,Mono,Gtk#,以某种模糊的方式,一个没有添加新功能的派生类的行为与它的基类不同。派生类: public class MyCheckButton : CheckButton { public MyCheckButton(string label) : base(label) { } } MyCheckButton继承自(GTK#,Mono项目的一部分)CheckButton。但是,在以下代码段中,它们的行为不同: var button1 = new CheckButton("_foo"

以某种模糊的方式,一个没有添加新功能的派生类的行为与它的基类不同。派生类:

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带下划线。但是,对于按钮2,这失败了。我只是在对话框中将“_foo”作为标签

有人能解释一下这个例子中的派生类是如何表现出不同的行为的吗?或者在屏幕后面是否有一些魔术,可能会检查实际类的类型

[一] 屏幕后面有一些魔法,也许可以检查 实际类的类型

事实上,有:

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。将
标签
包装在
对象中可能会弄乱记忆功能


让这成为一个教训(给GTK设计师):不要违反规则。真让人困惑

原因如下,请查看CheckButton的源代码:

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不遵循相同的代码路径

MyCheckButton的此代码是否全部显示在此处?如果不添加button1怎么办?也许它不喜欢两个“f”助记符?是的,这就是所有的代码。我尽可能地简化了这个例子。这两个相同的记忆法不是问题所在。我试过了。助记符在前一个路径中消失了,因为按钮的“use underline”属性没有设置为True,就像在本机
gtk\u check\u button\u new\u with_mnemonic()
构造函数中一样。应在数组列表中添加“使用下划线”的真对。这不是故意违反替代原则,这是一个bug,应该在报告时报告。