Làm cách nào để truy cập vào biến hỗ trợ của thuộc tính được triển khai tự động?


79

Trong quá khứ, chúng tôi đã khai báo các thuộc tính như sau:

public class MyClass
{
    private int _age;

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

Bây giờ chúng ta có thể làm:

public class MyClass
{
    public int Age {get; set;} 
}

Câu hỏi của tôi là, làm cách nào tôi có thể truy cập vào biến private được tạo tự động bằng cách sử dụng ký hiệu này?

Tôi muốn truy cập biến private chứ không phải truy cập công khai 'Age'. Có ký hiệu mặc định để truy cập biến private hay không?


10
Sự khác biệt trong trường hợp truy cập private và public accessor này là gì? Tôi nghĩ cách tốt nhất là truy cập trình truy cập công khai ngay cả từ logic trong lớp khai báo. Nếu bạn thêm một số logic vào trình truy cập, bạn không muốn phải thay đổi tất cả mã của mình.
Eric Schoonover 14-08

@ thìa16 Bạn có thể cho tôi một ví dụ về việc thêm logic vào bộ truy cập và kết quả là phải thay đổi tất cả mã của bạn. Tôi không thực sự hiểu phần này.
Ogen

Câu trả lời:


92

Mục đích của các thuộc tính tự động mới là giảm số lượng mã soạn sẵn bạn cần viết khi bạn chỉ có một thuộc tính đơn giản không cần bất kỳ logic đặc biệt nào trong get hoặc set.

Nếu bạn muốn truy cập thành viên riêng tư mà các thuộc tính này sử dụng, đó thường là vì một số lý do:

  • Bạn không chỉ cần một get / set đơn giản - trong trường hợp này, bạn chỉ nên tránh sử dụng các thuộc tính tự động cho thành viên này.
  • Bạn muốn tránh ảnh hưởng của màn trình diễn khi đi qua phần bắt đầu hoặc tập hợp và chỉ sử dụng trực tiếp thành viên - trong trường hợp này, tôi sẽ rất ngạc nhiên nếu thực sự có một thành công trình diễn. Các thành viên get / set đơn giản rất dễ nội tuyến và trong thử nghiệm (được thừa nhận là có giới hạn) của tôi, tôi không tìm thấy sự khác biệt giữa việc sử dụng các thuộc tính tự động và truy cập trực tiếp vào thành viên.
  • Bạn chỉ muốn có quyền truy cập đọc công khai (tức là chỉ 'get') và lớp ghi trực tiếp cho thành viên - trong trường hợp này, bạn có thể sử dụng tập hợp riêng tư trong thuộc tính tự động của mình. I E

    public class MyClass
    {
        public int Age {get; private set;} 
    }

Điều này thường bao gồm hầu hết các lý do muốn truy cập trực tiếp vào trường hỗ trợ được sử dụng bởi các thuộc tính tự động.


Đúng - họ làm giảm mã bowlerplate và tôi cũng sẽ quảng cáo rằng họ giảm những gì bạn cần kiểm tra. Một số người có thể cho rằng bạn cần kiểm tra get / set thủ công nhưng không phải với các thuộc tính tự động vì bạn có thể tin tưởng vào framework.
Daniel Auger 14/09/08

3
Mẫu mã sai ở đây. Nó phải là lớp công khai MyClass {public int Age {get; private set;}} Tôi đồng ý với câu trả lời này. Bạn không thể truy cập vào trường riêng tư và nếu cần, thì ngay từ đầu bạn không nên sử dụng Thuộc tính tự động.
hwiechers 14/09/08

hwiechers, cảm ơn vì điều đó - tôi đã có bản chỉnh sửa đó, nhưng khi cố gắng sửa định dạng, tôi phải nhấn dán lại và xóa khối mã sai. Doh!
Wilka 14/09/08

Thường được sử dụng trong các đối tượng POCO
RobS

23

Việc bạn sử dụng các thuộc tính tự động ngụ ý rằng bạn không cần bất kỳ logic nhận / cài đặt nào cho thuộc tính, do đó, một biến hỗ trợ riêng là không cần thiết.

Không sử dụng thuộc tính tự động nếu bạn có bất kỳ logic phức tạp nào trong lớp của mình. Chỉ cần đi private int _agevà getters / setters bình thường như bạn thường làm.

IMO, các thuộc tính tự động phù hợp hơn để triển khai nhanh chóng các đối tượng bỏ đi hoặc các viên dữ liệu tạm thời như:

public class TempMessage {
    public int FromID { get; set; }
    public int ToID { get; set; }
    public string Message { get; set; }
}

Nơi bạn không cần nhiều logic.


Tại sao việc thêm logic phức tạp vào lớp của bạn sẽ ảnh hưởng đến việc bạn có sử dụng các thuộc tính tự động trong lớp đó hay không?
Eric Schoonover 14/09/08

Điều nhất quán hơn nữa ... nếu bạn có logic phức tạp thì bạn sẽ muốn truy cập nó từ biến số sao lưu riêng theo thực tiễn OO .. và nếu bạn sử dụng thuộc tính tự động thì ... sẽ có sự mâu thuẫn trong việc truy cập các thuộc tính đó . vì một số sẽ có tiền tố gạch dưới và một số thì không.
chakrit

12

Cú pháp này thường được gọi là "đường cú pháp", có nghĩa là trình biên dịch lấy cú pháp đó và dịch nó thành một thứ khác. Trong ví dụ của bạn, trình biên dịch sẽ tạo mã trông giống như sau:

[CompilerGenerated]
private int <Age>k_BackingField;

public int Age
{
   [CompilerGenerated]
   get
   {
      return this.<Age>k_BackingField;
   }
   [CompilerGenerated]
   set
   {
      this.<Age>k_BackingField = value;
   }

Ngay cả khi biết tất cả những điều đó, bạn có thể truy cập trực tiếp vào trường hỗ trợ nhưng kiểu đó đã đánh bại mục đích của việc sử dụng các thuộc tính tự động. Tôi nói có lẽ ở đây vì khi đó bạn phụ thuộc vào một chi tiết triển khai có thể thay đổi bất kỳ lúc nào trong bản phát hành trình biên dịch C # trong tương lai.



7

Bạn không nên, và rất ít khả năng bạn cần. Nếu bạn cần truy cập thuộc tính, chỉ cần sử dụng thuộc tính công cộng (ví dụ: this.Age). Không có gì đặc biệt về lĩnh vực tư nhân ủng hộ tài sản công, sử dụng nó để thay thế tài sản chỉ là mê tín.


1
Tôi luôn tự hỏi điểm của thuộc tính tự động là gì. Nếu bạn không có logic đặc biệt nào trong getters và setters của mình tại sao lại có chúng?
Matthew Lock

4
@MatthewLock tính linh hoạt. Với quyền truy cập trường trực tiếp, bạn bị khóa vào thiết kế đó trừ khi bạn thay đổi tất cả mã khách hàng cùng một lúc. Nhưng với một thuộc tính nếu bạn quyết định thay đổi nó từ "trường giả" thành một thuộc tính được tính toán hoặc nếu bạn quyết định thêm các xác nhận và kiểm tra trên setter hoặc what-have-you, bạn có thể làm như vậy một cách minh bạch. Điều này thậm chí còn hữu ích hơn nếu bạn đang viết mã thư viện, nơi bạn không thể kiểm soát tất cả mã máy khách.
Wedge

2

Bạn không thể, đó là một tính năng ngôn ngữ trái ngược với một tính năng IDE. Thành thật mà nói, tôi muốn IDE thêm biến private vào cho bạn. Tôi đồng ý rằng hơi kỳ lạ khi nội bộ lớp phải sử dụng điểm vào công khai để truy cập các biến của chính nó. Do đó, bản thân tôi không sử dụng tính năng mới này nhiều.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.