2010-11-18 29 views
7

Tôi gặp vấn đề sau đây:Vấn đề với nhà thầu và kế thừa trong C#

public class A { 
    public A(X, Y, Z) { 
    ... 
    } 
} 

public class B : A { 
    public B(X, Y) : base(X, Y) { 
     //i want to instantiate Z here and only then pass it to the base class! 
    } 
} 

Làm thế nào tôi có thể giải quyết vấn đề này? Là có một cách?

+0

gì? là 'B: A'? Nếu vậy, A có thể có * nhiều * dữ liệu hơn B như thế nào? Ngoài ra, A dường như không có một nhà xây dựng như vậy ... – Kobi

+0

Bạn có nghĩa là lớp công khai B: A {trong ví dụ của bạn? –

+0

Đã chỉnh sửa bài đăng gốc. Có, B: A –

Trả lời

13

Giải pháp phổ biến là gọi một phương thức tĩnh thuộc loại có thể tính toán giá trị của tham số được truyền cho hàm tạo cơ sở.

Ví dụ:

public B(int x, int y) 
    : base(x, y, CalculateZ(x, y)) 
{ 

} 

// You can make this parameterless if it does not depend on X and Y 
private static int CalculateZ(int x, int y) 
{ 
    //Calculate it here. 

    int exampleZ = x + y; 

    return exampleZ; 
} 

Do lưu ý rằng CalculateZ không thể là một phương pháp dụ, bởi vì this tham chiếu là không có sẵn trong initializers constructor.

Từ initializers Constructor ngôn ngữ đặc tả 10.11.1:

Một ví dụ nhà xây dựng initializer không thể truy cập dụ là tạo. Do đó, đây là lỗi biên dịch để tham chiếu này trong biểu thức đối số của trình khởi tạo hàm khởi dựng , vì nó là một lỗi biên dịch đối số tham chiếu để tham chiếu đến bất kỳ cá thể đơn giản nào .

EDIT: Đã thay đổi 'mẫu' thành 'tĩnh' trong mô tả.

+1

+1, nhưng bạn không có nghĩa là nó hợp pháp để gọi * static * phương pháp? – LukeH

+0

@Kobi, @LukeH: Là lỗi đánh máy não; tâm trí nghĩ một điều và những ngón tay khác. Cảm ơn đã chỉ ra điều đó. – Ani

1
public abstract class A { 
    public A(X, Y) { 
    ... 
    } 

    public abstract Z TheVariableZ{get;set;} 
} 

public class B : A { 
    public B(X, Y) : base(X, Y) { 
     //i can only calculate Z here! 
    } 

    public override Z TheVariableZ{//implement it here} 
} 

Và nếu bạn không thể đưa ra một trừu tượng, chỉ cần đánh dấu các tài sản như ảo

+3

Gọi một phương thức ảo trong một hàm tạo là một ý tưởng tồi: http://msdn.microsoft.com/en-us/library/ms182331(v=VS.100).aspx –

1

Có thể này:

public abstract class A { 
    public A(X, Y) { 
     CalculateZ(); 
    } 

    abstract void CalculateZ(); 
} 

public class B : A { 
    public B(X, Y) : base(X, Y) { 

    } 

    override void CalculateZ() 
    { 
     ... Calculate here. 
    } 
} 
+3

Gọi một phương thức ảo trong một nhà xây dựng là một ý tưởng tồi: http://msdn.microsoft.com/en-us/library/ms182331(v=VS.100).aspx –

2

Bạn cần tính Z trước bản thân hàm tạo được gọi. Nếu nó đơn giản, bạn có thể sử dụng một biểu thức nội tuyến, nếu không bạn sẽ cần định nghĩa một hàm trợ giúp.

Sử dụng một helperfunction:

public class A { 
    public A(X x, Y y, Z z) { 
    ... 
    } 
} 

public class B : A { 
    private static Z calculateZ() 
    { 
    } 

    public B(X x, Y y) : base(X, Y, calculateZ()) { 

    } 
} 

Without helperfunction:

public B(X, Y) : base(X, Y, X+Y) { 

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