Why is this derived class different from it with a base class

In some obscure way, a derived class that does not add new functionality (for now) behaves different from the base class. Derived class:

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

MyCheckButton inherits from (GTK #, part of the Mono project) CheckButton. However, in the following code snippet, they behave differently:

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

An underscore on a label ensures that the label becomes mnemonic. For button1, this works in my test code: I get "foo" where f is underlined. However, for button 2, this fails. I just get "_foo" as a label in my dialog box.

Can someone explain how the derived class in this example can behave differently or is there some kind of magic coming up behind the screen that might check the type of the actual class?

+7
source share
2 answers

[I] is there some kind of magic coming up behind the screen, which perhaps checks the type of the actual class?

Actually, there are:

 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); } } 

It looks like your subclass will follow the same route. Not sure why this will ruin the mnemonics; the last method is P / Invoke in the gtk native library. It is possible that the label wrapper in the Value object destroys the mnemonic.

Let this be a lesson (to GTK # designers): don't violate the Liskov Principle of Replacement . This is confusing!

+7
source

Here's why, look at the source for 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); } 

Derived types do not match the same code as CheckButton in .ctor

+2
source

All Articles