2012-06-20 78 views
7

Tôi có một lớp với hai hàm tạo (C#). Đây là đoạn mã:Gọi một hàm tạo từ một hàm tạo khác trong cùng một lớp

public class FooBar() 
{ 
    public FooBar(string s) 
    { 
     // constructor 1, some functionality 
    } 

    public FooBar(int i) : this("My String") 
    { 
     // constructor 2, some other functionality 
    } 

} 

Vâng, tôi biết rằng tôi có thể gọi một hàm tạo từ một phương thức khác bằng cách sử dụng phương pháp được đề cập ở trên. Nhưng trong trường hợp này, nếu tôi gọi hàm tạo 2, tất cả các câu lệnh trong hàm tạo 1 sẽ chạy TRƯỚC KHI câu lệnh rất trong hàm tạo 2 được thi hành.

Những gì tôi muốn là sau khi tất cả các câu trong constructor 2 đang chạy, sau đó nó sẽ gọi constructor 1.

Trong tình huống chính xác của tôi, tôi đang làm xác thực người dùng. Constructor 1 lấy thông tin người dùng chỉ với ID người dùng, nhưng hàm tạo 2 thực hiện xác thực người dùng bằng email và mật khẩu. Nếu người dùng nằm trong cơ sở dữ liệu, nó nhận được ID người dùng và bây giờ tôi muốn hàm tạo 1 để điền tất cả các thuộc tính của lớp.

Vui lòng cho tôi biết nếu bạn cần thêm thông tin. Nếu bạn nghĩ rằng có một cách tiếp cận tốt hơn, tôi sẽ rất vui khi nghe đề xuất đó.

UPDATE 1: Tôi tự hỏi tại sao một cái gì đó như thế này không được thực hiện:

public FooBar(bool b) 
{ 
    // constructor 3, some more functionality 
    this.FooBar("My String"); // calling constructor 1 
} 
+2

Thú vị scenerio. Bạn có thể di chuyển chức năng trong một hàm riêng biệt, hoặc tạo ra một Constructor quá tải 'FooBar (chuỗi s, int i)'. Có thể không phải là giải pháp tốt nhất, nhưng chỉ cần ném ra một số ý tưởng. – Justin

+0

@Justin, đặt logic trong một phương pháp khác có vẻ là một ý tưởng tốt hơn. Cảm ơn. – Farhan

Trả lời

7

Trong trường hợp này chỉ không sử dụng lời gọi constructor, nhưng cái gì đó như:

public class FooBar() 
{ 
    public FooBar(string s) 
    { 
     Init1(); 
    } 

    public FooBar(int i) 
    { 
     Init2(); 
     Init1(); 
    } 

} 

Nơi tôi cho rằng Init1(..)Init2(..) được phương pháp liên quan đến một số logic intialization cụ thể của constructor tương ứng.

Thực ra bạn có thể sắp xếp cuộc gọi hàm này theo cách phù hợp hơn với nhu cầu của bạn.

2

Tại sao không quấn chức năng đó vào một số method và gọi đó là trong constuctors (hoặc bất cứ nơi nào bạn muốn)?

public class FooBar() 
{ 
    public FooBar(string s) 
    { 
     LoadUser(s); 
    } 

    public FooBar(int i) : this("My String") 
    { 
     var s=CheckUser(); 
     LoadUser(s); 
    } 

    private string CheckUser() 
    { 
     return "the id/name from db"; 
    } 
    private void LoadUser(string s) 
    { 
      //load the user 
    } 

} 

Đây là giải pháp chung. Bạn có thể thay đổi kiểu trả về theo kịch bản cụ thể của bạn.

2

Nói chung bạn có thể sử dụng này:

public class FooBar() 
{ 
    private Test(string s) 
    { 
     // Some functionality 
    } 

    public FooBar(string s) 
    { 
     Test(s); 
    } 

    public FooBar(int i) 
    { 
     // Do what you need here 
     Test("MyString"); 
    }  
} 
1

Cách tiếp cận tốt nhất - không đặt logic đó trong hàm tạo. Phá vỡ nó ra các phương pháp khác mà bạn có thể gọi theo ý muốn mà không lo lắng về việc xây dựng chuỗi.

+0

Cảm ơn. Tôi đồng ý rằng xây dựng chuỗi có thể gây nhầm lẫn, và tôi có thể không nhận được chính xác những gì tôi cần. Tôi sẽ sử dụng các phương pháp riêng khác. – Farhan

8

Bạn có thể sử dụng một phương pháp riêng để thực hiện khởi tạo:

public class FooBar() 
{ 
    public FooBar(string s) 
    { 
     this.Initialize(s); 
    } 

    public FooBar(int i) 
    { 
     this.Initialize("My String"); 
    } 

    private void Initialize(string s) { 
     // Do what constructor 1 did 
    } 
} 
Các vấn đề liên quan