2012-02-26 25 views
15

Tôi đang làm việc trên một dự án liên quan đến rất nhiều giao tiếp và kế thừa, điều này đang bắt đầu hơi phức tạp và giờ tôi đã gặp sự cố.Sử dụng 'this' trong hàm tạo cơ sở?

Tôi có một trạng thái lớp trừu tượng có đối tượng Game làm đối số hàm tạo. Trong constructor của lớp Game của tôi, nó sẽ ở trong trạng thái. Ý tưởng là khi kế thừa từ lớp cơ sở trò chơi trừu tượng, khi gọi hàm tạo của lớp cơ sở, bạn cho nó một đối tượng trạng thái ban đầu. Tuy nhiên đối tượng này của Nhà nước có trong cùng một Trò chơi mà bạn đang tạo. Mã này trông giống như sau:

public class PushGame : ManiaGame 
{ 
    public PushGame() : 
      base(GamePlatform.Windows, new PlayState(this), 60) 
    { 
    } 
} 

Tuy nhiên điều này không hiệu quả. Tôi chỉ có thể giả định vì từ khóa 'này' không thể sử dụng được cho đến sau khi hàm tạo đã bắt đầu thực thi. Cố gắng sử dụng nó trong constructor của lớp cơ sở của bạn không hoạt động, rõ ràng. Vì vậy, cách giải quyết tốt nhất của tôi cho điều này là gì? Kế hoạch của tôi B là xóa bỏ đối số State khỏi hàm tạo của lớp Game và chỉ cần thiết lập trạng thái bên trong mã của hàm tạo sau đó.

Có cách nào dễ dàng hơn, ít xâm nhập hơn để thực hiện việc này không?

+1

Vui lòng không thêm tiền tố vào tiêu đề của bạn bằng "C#". Đó là những gì các thẻ cho. –

Trả lời

9

Rõ ràng lớp ManiaGame luôn luôn sử dụng các đối tượng của loại PlayState, vì vậy bạn có thể di chuyển tạo ở cấp ManiaGame:

public class PushGame : ManiaGame 
{ 
    public PushGame() : base() 
    { 
    } 

} 

public class ManiaGame 
{ 
    PlayState ps; 
    public ManiaGame() { 
     ps = new PlayState(this); 
    } 
} 

Nếu bạn muốn lớp PlayState cụ thể hơn ..

public class PushGame : ManiaGame 
{ 
    public PushGame() : base() 
    { 
    } 
    protected override PlayState CreatePlayState() 
    { 
     return new PushGamePlayState(this); 
    } 
} 

public class ManiaGame 
{ 
    PlayState ps; 
    public ManiaGame() { 
      ps = CreatePlayState(); 
    } 
    protected virtual PlayState CreatePlayState() 
    { 
     return new PlayState(this); 
    } 
} 

public class PlayState 
{ 
    public PlayState(ManiaGame mg) {} 
} 


public class PushGamePlayState : PlayState 
{ 
    public PushGamePlayState(ManiaGame mg) : base(mg){} 
} 
+0

+1 và nó cũng nhấn mạnh sự phụ thuộc đồng thời giữa ManiaGame và PlayState, do đó, 2 đối tượng không bao giờ có thể được tham chiếu chéo "đồng thời" trong các nhà xây dựng tương ứng. – StuartLC

+1

Điều quan trọng cần lưu ý là việc gọi một phương thức ảo từ bên trong ctor có thể nguy hiểm - http://stackoverflow.com/questions/119506/virtual-member-call-in-a-constructor – AlexD

0

Dường như 'this' chỉ có thể được sử dụng để tham chiếu một hàm tạo khác trong ngữ cảnh đó.

Đó là, điều này được sử dụng như một từ khóa Phạm vi trước khi các nhà xây dựng thực hiện:

: this("ParameterForAnotherConstructor") 

Nhưng nó không phải là có sẵn như là tài liệu tham khảo thông thường của nó đến thể hiện đẳng cấp,

: base(this) // Keyword this is not available in this context 

Và rõ ràng nó không thể gọi cho bất kỳ phương thức thể hiện nào là

: base(GetThis()) // Object reference is required 

Có một lỗi tràn bộ đếm tương tự estion, Keyword 'this' (Me) is not available calling the base constructor với cách khắc phục tương tự như đề xuất của bạn.

1

Nếu triển khai thực hiện State được sử dụng tùy thuộc vào lớp Game cụ thể, sau đó tôi sẽ tạo một phiên bản mới của State bên trong hàm tạo của lớp con Game (PushGame) và truy cập vào State trong lớp cơ sở thông qua thuộc tính abstract.

public class PushGame : ManiaGame 
{ 
    private readonly PlayState gamePlayState; 

    public PushGame() : base() 
    { 
     gamePlayState = new PlayState(this); 
    } 

    protected override State GamePlayState 
    { 
     get { return gamePlayState; } 
    } 
} 

public abstract class ManiaGame 
{ 
    protected abstract State GamePlayState { get; } 
} 

public class State 
{ 
    public State(ManiaGame mg) { } 
} 


public class PlayState : State 
{ 
    public PlayState(ManiaGame mg) : base(mg) { } 
} 
0

Liệu thiết kế của bạn phân biệt giữa một trò chơi (nói backgammon) và một trò chơi cơ bản dở dang (một trò chơi backgammon)? Nếu bạn đang cố gắng kết hợp hai khái niệm này thì tôi sẽ đề xuất mô hình hóa chúng một cách riêng biệt. Ví dụ: Backgammon và BackgammonContest.

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