2017-09-05 13 views
151

Đôi khi tôi thấy chữ viết tắt trong thuộc tính cho bộ thu thập. Ví dụ. hai loại đó:Sự khác biệt trong C# giữa các kiểu getter khác nhau

public int Number { get; } = 0 

public int Number => 0; 

Ai đó có thể vui lòng cho tôi biết nếu có bất kỳ sự khác biệt nào giữa hai loại đó. Họ cư xử như thế nào? Cả hai đều chỉ đọc?

Trả lời

262

Có, cả hai đều chỉ đọc, nhưng có sự khác biệt. Trong trường hợp đầu tiên, có một trường sao lưu được khởi tạo là 0 trước khi hàm tạo được thực hiện. Bạn chỉ có thể thay đổi giá trị chỉ trong hàm tạo, giống như trường chỉ đọc thông thường. Bản thân getter chỉ trả về giá trị của trường.

Trong bước thứ hai, trình lấy chỉ trả về 0 mỗi lần, không có trường liên quan.

Vì vậy, để tránh sử dụng bất kỳ thuộc tính tự động thực hiện hoặc các thành viên biểu hiện thân ở tất cả, chúng ta có:

Đầu tiên phiên bản

private readonly int _number = 0; 
public int Number { get { return _number; } } 

phiên bản thứ hai

public int Number { get { return 0; } } 

Một ví dụ rõ ràng về sự khác biệt có thể được nhìn thấy như sau:

public DateTime CreationTime { get; } = DateTime.UtcNow; 
public DateTime CurrentTime => DateTime.UtcNow; 

Nếu bạn tạo một đối tượng duy nhất, thuộc tính CreationTime sẽ luôn cho kết quả tương tự - vì nó được lưu trữ trong trường chỉ đọc, được khởi tạo trên đối tượng xây dựng. Tuy nhiên, mỗi khi bạn truy cập thuộc tính CurrentTime, điều này sẽ khiến cho DateTime.UtcNow được đánh giá, do đó bạn sẽ nhận được kết quả có khả năng khác.

+22

Lưu ý rằng phiên bản thứ hai không phải lúc nào cũng trả lại cùng một giá trị. Một ví dụ tốt là nếu bạn trả về 'random.NextInt()'. Phiên bản đầu tiên sẽ đánh giá một lần và luôn có cùng giá trị. Thứ hai sẽ trả về một giá trị mới mỗi lần. – Hosch250

20

Đây là các tính năng ngôn ngữ C# 6.

dụ đầu tiên

public int Number { get; } = 0 

Ví dụ đầu tiên là một getter-only auto property. Trường sao lưu của thuộc tính tự động chỉ getter được ngầm khai báo là chỉ đọc.

Thứ hai ví dụ

public int Number => 0; 

Và ví dụ thứ hai là expression bodies on property-like function members. Lưu ý rằng không có bất kỳ từ khóa get nào: Nó được ngụ ý bằng cách sử dụng cú pháp thân của biểu thức.

Cả hai đều chỉ đọc.

+4

... nhưng như Jon Skeet giải thích, bạn có thể thay đổi giá trị đầu tiên trả về. –

+1

@MartinBonner ... nhưng chỉ trong hàm tạo. –

+4

hoặc, như mọi khi, thông qua phản ánh (nhỏ nitpicking) –

246

Một khác biệt là khi đó 0 được đánh giá: khi tạo đối tượng hoặc khi thuộc tính được sử dụng.

Bạn có thể thấy điều này tốt hơn với tính DateTime:

class SomeTestClass 
{ 
    public DateTime Start { get; } = DateTime.Now; 

    public DateTime Now => DateTime.Now; 
} 

Thuộc tính Start tiếp tục quay trở lại cùng một lúc (trong khi các trường hợp đã được tạo ra), trong khi Now thay đổi để phản ánh thời gian hiện tại.

Giải thích:

Phiên bản đầu tiên ("Start") cung cấp một giá trị ban đầu mà thậm chí có thể được ghi đè bởi các nhà xây dựng. Vì vậy, điều này được đánh giá chỉ một lần.
Phiên bản thứ hai ("Bây giờ") cung cấp biểu thức sẽ là "getter" của thuộc tính này. Vì vậy, điều này được đánh giá mỗi khi tài sản được đọc. Thậm chí không có trường sao lưu mà hàm tạo có thể ghi đè lên.

+24

Đây là sự khác biệt quan trọng nhất mà tôi nghĩ. – Matthew

+13

Câu trả lời được chấp nhận định nghĩa chính xác nhất sự khác biệt trong mã ví dụ, nhưng điều này giải thích sự khác biệt hữu ích hơn trong hai cấu trúc. –

+2

Wow, bạn có nhiều phiếu bầu hơn bản thân Jon Skeet nổi tiếng. –

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