2013-05-14 51 views
5

Trong C#, lớp A chứa phương thức công khai Foo() xử lý một số và trả về một giá trị. protected phương thức Bar(), cũng trong lớp A thực hiện cùng một logic như Foo(), tiếp theo là một số xử lý bổ sung và sau đó trả về một giá trị.Phương thức cơ sở cuộc gọi thay vì ghi đè

Để tránh trùng lặp mã, Bar() gọi Foo() và sử dụng lợi nhuận dưới dạng giá trị trung gian.

class A 
{ 
    public virtual String Foo() 
    { 
    String computedValue; 
    // Compute the value. 
    return computedValue; 
    } 

    protected String Bar() 
    { 
    String computedValue; 
    String intermediateValue = Foo(); 
    /// More processing to create computedValue from intermediateValue. 
    return computedValue; 
    } 
} 

Lớp B thừa hưởng từ A và ghi đè Foo(). Ghi đè gọi triển khai lớp cơ sở là Bar().

class B : A 
{ 
    public override String Foo() 
    { 
    base.Bar(); 
    } 
} 

Điều này (tất nhiên) đi vào vòng lặp vô hạn cho đến khi máy tính hết bộ nhớ và sau đó tạo ra ngoại lệ tràn ngăn xếp.

Giải pháp rõ ràng nhất là viết lại A với phương thức riêng FooInternals chứa đường ruột của Foo. Foo và Bar sau đó được sửa đổi để sử dụng các kết quả của phương thức đó.

Có cách nào buộc A's Bar() gọi số A Foo() thay vì ghi đè không?

(tôi gần như chắc chắn là cách quá thông minh ở đây, điều này đi hoàn toàn chống lại đa hình Nhưng tôi không thể cưỡng lại sự ham muốn thử đẩy hiểu biết của tôi một chút nữa..)

Trả lời

7

Có cách nào để buộc A's Bar() gọi A's Foo() thay vì ghi đè?

Không trực tiếp. Các refactoring đơn giản sẽ được thay đổi Foo tới:

public virtual string Foo() 
{ 
    return FooImpl(); 
} 

private string FooImpl() 
{ 
    String computedValue; 
    // Compute the value. 
    return computedValue; 
} 

Sau đó thay đổi Bar gọi FooImpl thay vì Foo.

(Đây có lẽ là những gì bạn có nghĩa là trong "giải pháp rõ ràng nhất" đoạn của bạn -. Mà tôi bỏ lỡ trên bài đọc thứ nhất, tôi sợ)

Về cơ bản điều này chỉ là một trong những lĩnh vực mà thừa kế là vấn đề . Khi một phương thức ảo gọi một phương thức khác, cần phải được ghi lại để các lớp con có thể tránh gây ra các vấn đề - mặc dù nó có cảm giác như là nên là một chi tiết triển khai. Đây là thứ khiến tôi thích sáng tác hơn thừa kế - cả hai đều là những lựa chọn hợp lý, tất nhiên.

+0

Cảm ơn, tôi đã cho rằng đó là cách tiếp cận tốt nhất/rõ ràng nhất. Chỉ cần tự hỏi nếu tôi có thể đã bỏ lỡ một sự thay thế. – ThatBlairGuy

+1

@ThatBlairGuy: Rất tiếc, tôi đã bỏ lỡ đoạn văn trong câu trả lời của bạn mô tả điều đó. Rất tiếc :) Nhưng không, đó là tất cả những gì bạn có thể làm thực sự. –

+0

Không phải lo lắng, cảm ơn vì đã xác minh rằng tôi không nhìn thấy gì đó. – ThatBlairGuy

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