2009-02-17 53 views
7

Khi tôi khởi tạo một đối tượng bằng cách sử dụng bộ khởi tạo đối tượng mới trong C#, tôi không thể sử dụng một trong các thuộc tính trong lớp để thực hiện thêm hành động và tôi không biết tại sao.Tôi đang làm gì sai với bộ khởi tạo đối tượng C#?

mã ví dụ của tôi:

Person person = new Person { Name = "David", Age = "29" }; 

Trong lớp Person, x sẽ bằng 0 (mặc định):

public Person() 
{ 
    int x = Age; // x remains 0 - edit age should be Age. This was a typo 
} 

Tuy nhiên person.Age làm bằng 29. Tôi chắc chắn điều này là bình thường, nhưng tôi muốn hiểu tại sao.

+0

Độ tuổi trong hàm tạo của bạn có phải là tất cả chữ thường hoặc titlecase giống như thuộc tính của bạn không? Điều đó có thể đi một cách để xác định vấn đề –

+0

không có nó nên là tuổi. Xin lỗi typo – dmce

Trả lời

21

Thuộc tính được đặt cho Tên và tuổi sau khi hàm tạo công khai() của người xây dựng() đã kết thúc chạy.

Person person = new Person { Name = "David", Age = "29" }; 

tương đương với

Person tempPerson = new Person() 
tempPerson.Name = "David"; 
tempPerson.Age = "29"; 
Person person = tempPerson; 

Vì vậy, trong các nhà xây dựng Tuổi sẽ không đã trở thành 29 được nêu ra.

(tempPerson là một tên biến duy nhất bạn không thấy trong mã của bạn sẽ không đụng độ với các cá thể người khác được xây dựng theo cách này. TempPerson là cần thiết để tránh các vấn đề đa luồng, việc sử dụng nó đảm bảo rằng đối tượng mới không trở thành có sẵn cho bất kỳ thread khác cho đến khi sau khi các nhà xây dựng đã được thực hiện và sau khi tất cả các thuộc tính đã được khởi tạo.)


Nếu bạn muốn để có thể thao tác các tài sản Tuổi trong các nhà xây dựng, sau đó Tôi khuyên bạn nên tạo một hàm tạo có độ tuổi làm đối số:

public Person(string name, int age) 
{ 
    Name = name; 
    Age = age; 

    // Now do something with Age 
    int x = Age; 
    // ... 
} 
+0

điều này là sai, xem câu trả lời mới hơn – juan

+0

Không phải là câu lệnh đầu tiên trong câu trả lời chính xác mặc dù "Thuộc tính được đặt cho Tên và tuổi sau công thức của người xây dựng() 'đã kết thúc chạy." – dmce

+0

@Juan: Bạn đang phần nào không hiểu được ý kiến ​​của mình về "điều này là sai". Trong khi câu trả lời này là hơi không chính xác liên quan đến việc không tham chiếu biến tạm thời, nó không phải là sai đối với câu hỏi được hỏi. Cố gắng lịch sự hơn, vì sợ rằng đó là câu hỏi hoặc câu trả lời của bạn trong lần tới. –

3

Dường như bạn đang cố truy cập Age trong hàm tạo của đối tượng. Các giá trị khởi tạo đối tượng sẽ không được đặt cho đến sau khi hàm tạo đã thực hiện.

Hãy thử điều này:

Person person = new Person { Name = "David", Age = 29 }; 
int x = person.Age; 

EDIT để phản ứng lại bình luận

Nếu bạn cần truy cập vào Age trong các nhà xây dựng chính nó sau đó bạn sẽ cần phải tạo ra một constructor rõ ràng với các tham số bắt buộc và sử dụng thông số đó thay vì cú pháp khởi tạo đối tượng. Ví dụ:

public class Person 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 

    public Person(string name, int age) 
    { 
     Name = name; 
     Age = age; 

     int x = Age; // will be 29 in this example 
    } 
} 

Person person = new Person("David", 29); 
+0

downvotes không giải thích được là một bệnh dịch hạch –

+1

bỏ phiếu chỉ để p.o. bất cứ ai downvoted –

+0

Có điều này làm việc cho tôi nhưng tôi muốn làm một cái gì đó với tuổi khi tôi vẫn còn trong constructor – dmce

6

dòng của bạn mã giống hệt:

Person person = new Person() { Name = "David", Age = "29" }; 

mà giống hệt:

Person person = new Person(); 
person.Name = "David"; 
person.Age = "29"; 

Như bạn có thể nhìn thấy; khi hàm tạo thi hành, Age chưa được đặt.

+0

"Khi constructor thực hiện, Tuổi vẫn là 29"? Có thật không? –

+0

Rất tiếc - bạn biết ý tôi là gì ;-p –

+0

điều này là sai, hãy xem các câu trả lời mới hơn – juan

9

Lưu ý, như một chi tiết kỹ thuật quan trọng, đó là:

Person person = new Person { Name = "David", Age = "29" }; 

tương đương với:

Person <>0 = new Person(); // a local variable which is not visible within C# 
<>0.Name = "David"; 
<>0.Age = "29"; 
Person person = <>0; 

nhưng không tương đương với:

Person person = new Person(); 
person.Name = "David"; 
person.Age = "29"; 
+0

Tại sao điều này lại quan trọng? Tôi không thấy bất kỳ sự khác biệt nào trong hiệu ứng. –

+0

+1 chỉ để đánh tôi với nó ... bạn là wcoenen chính xác, bạn sẽ không thấy sự khác biệt ... cho đến khi một chủ đề khác nhau cố gắng đọc Person.Name - nhưng không thực sự được thiết lập vì <> 0.Name là ... –

+0

Vâng, đa luồng là lý do chi tiết kỹ thuật này là quan trọng. – yfeldblum

4

Về mặt kỹ thuật, mã này:

Person person = new Person { Name = "David", Age = 29 }; 

là giống với mã này:

Person tmpPerson = new Person(); 
tmpPerson.Name = "David"; 
tmpPerson.Age = 29; 
Person person = tmpPerson; 

đó là hơi khác với những gì người khác đã đăng:

Person person = new Person(); 
person.Name = "David"; 
person.Age = 29; 

Sự khác biệt này là rất quan trọng nếu ứng dụng của bạn đang sử dụng đa luồng.

0

Vâng, như những người khác nói, các nhà xây dựng parameterless đã thực hiện đầu tiên, do đó quandary của bạn.

Tôi phải hỏi tuy nhiên, nếu bạn đã đặt trường thay vì thuộc tính tự động cho biến Độ tuổi của bạn?

public class Person 
{ 
    private int _age; 

    public int Age 
    { 
     get { return _age; } 
     set { _age = value; } 
    } 
} 

Bạn có thể sử dụng _age thay vì x nếu đó là đủ, hoặc nếu bạn thực sự cần phải sử dụng x:

public class Person 
{ 
    private int _age; 
    private int x; 

    public int Age 
    { 
     get { return _age; } 
     set 
     { 
      _age = value; 
      x = _age; 
     } 
    } 
} 

Cho dù là thích hợp hơn.

+0

Tôi đã sử dụng Public int Age {get; set;} - các thuộc tính tự động – dmce

+0

dmce - chính xác. Các thuộc tính "thủ công" hoặc "truyền thống" sẽ giúp bạn giải quyết vấn đề này dễ dàng hơn. –

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