2010-10-03 24 views
5

Tôi có điều này:Tại sao phải bận tâm với initializers? (.net)

AudioPlayer player = new AudioPlayer(); 
player.Directory = vc.Directory; 
player.StartTime = vc.StarTime; 
player.EndTime = vc.EndTime; 

Nhưng tôi có thể có điều này:

AudioPlayer player = new AudioPlayer 
{ 
    Directory = vc.Directory, 
    StartTime = vc.StarTime, 
    EndTime = vc.EndTime 
}; 

Nếu tôi chuyển sang 'phương pháp mới để viết những thứ', để tôi đạt được những gì ngoài unreadability? Nó sẽ làm cho tôi gần gũi hơn với hàm lambda (=>)?

Có liên quan gì với RAII không?

ADDITION:

Một số trả lời rằng khởi bình thường có thể rời khỏi đối tượng trong 'hợp lệ' nhà nước sau khi ví dụ thiết lập chỉ là một tài sản xuất khẩu - quan sát của tôi ở đây là đó là người đã thiết kế các đối tượng có thể thiết kế nó trong một cách mà chỉ các giá trị PHẢI được nhập thực sự mới được nhập thông qua hàm tạo thực, và tất cả các giá trị khác có thể được sửa đổi tự do sau này.

+0

Vâng, có vẻ như linh cảm của tôi về lambdas là chính xác! –

+0

Kiểm tra sách ngôn ngữ C# yêu thích của bạn cho "các loại ẩn danh". –

+0

@Hans: như trong 'ad-hoc-property-containers'? –

Trả lời

2

Hãy xem xét bạn muốn chuyển đối tượng mới được tạo cho một số phương thức (và không làm bất kỳ điều gì khác với phương thức này). Bạn có thể có thể viết nó theo cách cũ:

AudioPlayer player = new AudioPlayer(); 
player.Directory = vc.Directory; 
player.StartTime = vc.StarTime; 
player.EndTime = vc.EndTime; 
some.Method(player); 

Hoặc bạn có thể sử dụng initializers đối tượng:

some.Method(
    new AudioPlayer 
    { 
     Directory = vc.Directory, 
     StartTime = vc.StarTime, 
     EndTime = vc.EndTime 
    }); 

Sử dụng initilizers đối tượng, bạn có thể thấy rõ những gì các mã lệnh thực hiện và rằng đối tượng không được sử dụng sau .

Ngoài ra, tôi nghĩ khả năng đọc (và "khả năng ghi") là tốt hơn: bạn không phải lặp lại tên biến không ngừng.

+0

Vâng, ở đây có từ khóa 'with' từ VB6! :) –

1

Tôi tin rằng cú pháp này đã được thêm vào vì nó dễ sử dụng hơn với biểu thức lambda, vì vậy bạn có thể thực hiện một việc dễ dàng như item => new Person() { Name = item.Name }.

Tôi không nghĩ rằng nó có liên quan đến RAII mặc dù ..

10

Với ví dụ đơn giản như vậy, bạn thực sự không đạt được nhiều. Tuy nhiên, nó sẽ khác đi, khi bạn có điều này:

var player = new AudioPlayer 
{ 
    Car = new Car() 
    { 
     WheelSize = new Inch(21), 
     Driver = new Person() 
     { 
      Age = 53, 
      Type = LicenseType.B, 
      Family = 
      { 
       new Person("Jane"), 
       new Person("Pieter"), 
       new Person("Anny") 
      } 
     } 
    } 
    Directory = vc.Directory, 
    StartTime = vc.StarTime, 
    EndTime = vc.EndTime 
}; 

Hãy thử làm điều này theo cách cũ. Nó thực sự xấu xí.

+0

+1. Một điểm tầm thường, nhưng các parantheses không được yêu cầu khi gọi constructor parameterless. – Ani

+0

@Ani: Đó là lý do tại sao 'AudioPlayer' mới không có dấu ngoặc đơn :-) – Steven

1

Bạn nhận được ít hơn 21 ký tự mã. Và ít mã hơn có nghĩa là ít lỗi hơn. Và để đạt được nhiều hơn, bạn có thể sử dụng suy luận kiểu biến tiềm ẩn: var player = new AudioPlayer {

2

Bạn không chỉ nhận được tính không đọc được, bạn còn có khả năng gây ra lỗi hơn bằng cách đặt đối tượng vào trạng thái không hợp lệ.

Điều duy nhất nó liên quan đến RAII là RAII phụ thuộc vào các bất biến hợp lý và các trình khởi tạo giúp dễ dàng phá vỡ các bất biến. Tuy nhiên, nó có thể rất hữu ích trong việc tạo ra một giá trị ẩn danh, hoặc trong việc tạo các đối tượng kiểu dữ liệu thuần cũ (trong đó lớp là một vùng chứa "giá trị" và các giá trị bất biến không quan trọng). Chúng có thể đặc biệt hữu ích với các hàm lambda và các biểu thức linq, mặc dù không hoàn toàn cần thiết đối với chúng, cũng như không bị hạn chế đối với chúng.

Khi một lớp duy trì một sự bất biến, thì không nên khởi tạo nó theo cách như vậy, và như một quy tắc viết lại từ một hàm tạo có giá trị cho cú pháp mới là một ý tưởng tồi.

Trong ví dụ của bạn, trường hợp đầu tiên của bạn không sử dụng hàm tạo của nó để khởi tạo trạng thái hợp lệ được bảo đảm. Đó là một mùi hôi, (một cầu thủ có ý định làm gì trước khi nó có thư mục, thời gian bắt đầu và thời gian kết thúc?) Nhưng khi nó hợp lý cho một lớp nhất định, thì việc sử dụng cú pháp mới là như thế.

Cú pháp mới có thể thiết lập đối tượng trong một biểu thức duy nhất, có thể là một phần của biểu thức khác, là nơi có thể hữu ích và có trong biểu thức lambda.

2

Trình khởi tạo trở thành bắt buộc và không chỉ hữu ích khi xử lý các loại ẩn danh.

ví dụ:

var x = new {Foo = "foo", Bar = "bar"};

+0

Ví dụ cụ thể này, nó có tương thích với .net 2.0 không? I E. nó là một tính năng của một IDE, trình biên dịch, hoặc .net thời gian chạy? –

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