2011-07-12 45 views
7

Trong một số cách mơ hồ, một lớp dẫn xuất không thêm chức năng mới (chưa) hoạt động khác với lớp cơ sở của nó. Lớp dẫn xuất:Tại sao lớp dẫn xuất này hoạt động khác với lớp cơ sở của nó

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

MyCheckButton kế thừa từ (GTK #, một phần của dự án Mono) Nút kiểm tra. Tuy nhiên, trong đoạn mã sau, chúng hoạt động khác nhau:

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

Dấu gạch dưới trong nhãn đảm bảo nhãn bị ghi nhớ. Đối với button1, nó hoạt động trong testcode của tôi: Tôi nhận được "foo" trong đó f được gạch dưới. Tuy nhiên đối với button2 này không thành công. Tôi chỉ nhận được "_foo" như một nhãn trong hộp thoại của tôi.

Bất cứ ai có thể giải thích làm thế nào lớp dẫn xuất trong ví dụ này có thể hoạt động khác hoặc có một số ma thuật xảy ra phía sau màn hình có thể kiểm tra loại của lớp thực tế?

+3

Là mã này MyCheckButton được tất cả các trình bày ở đây ? – Tigran

+2

Nếu bạn không thêm button1 thì sao? Có lẽ nó không giống như hai 'f' mnemonics? – dlev

+0

Có, đây là tất cả mã. Tôi đã làm ví dụ đơn giản nhất có thể. Hai phép nhớ giống nhau không phải là vấn đề. Tôi đã thử điều đó. –

Trả lời

7

[I] Có một số ma thuật xảy ra phía sau màn hình có thể kiểm tra loại của lớp thực tế?

Trên thực tế, có:

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

Dường như lớp con của bạn sẽ được đi con đường cũ. Không chắc chắn tại sao điều đó sẽ làm rối loạn sự nhớ lại, mặc dù; phương thức thứ hai là một P/Invoke trên thư viện gtk gốc. Có thể là gói label trong một đối tượng Value là mucking lên các công cụ ghi nhớ.

Hãy để đó là một bài học (đối với nhà thiết kế GTK #): không vi phạm số Liskov Substitution Principle. Thật khó hiểu!

+0

Biến mất tự động biến mất trong tuyến đường cũ vì thuộc tính "sử dụng gạch dưới" của nút không được đặt thành True, vì nó nằm trong hàm khởi tạo 'gtk_check_button_new_with_mnemonic()' gốc. Một "sử dụng gạch chân", cặp True nên được thêm vào danh sách mảng. Đây không phải là một sự cố ý vi phạm nguyên tắc thay thế, đó là một lỗi và cần được báo cáo tại http://www.mono-project.com/Bugs. – ptomato

+0

Tôi đã gửi báo cáo lỗi. –

2

Dưới đây là lý do tại sao, nhìn vào nguồn cho ctor 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); 
} 

nguồn gốc các loại không theo con đường mã tương tự như CheckButton trong .ctor

Các vấn đề liên quan