2009-02-19 19 views
7

Không chắc nếu tôi diễn đạt này một cách chính xác ... nhưng tôi có đoạn mã sau:Làm cách nào để đặt giá trị của thuộc tính chỉ đọc với getters và setters chung?

public Guid ItemId 
    { 
     get; 
    } 

    public TransactionItem() 
    { 
     this.ItemId = Guid.Empty; 
    } 

Đương nhiên tôi nhận được một vấn đề chỉ đọc ... mà tôi hiểu được. Liệu có cách nào để thiết lập giá trị tài sản này mà không cần phải làm điều gì đó giống như dưới đây:

Guid _itemId = Guid.Empty; 
    public Guid ItemId 
    { 
     get 
     { 
      return _itemId; 
     } 
     set 
     { 
      _itemId = value; 
     } 
    } 

hoặc

public Guid ItemId 
    { 
     get; 
     internal set; 
    } 

Cảm ơn trước!

Trả lời

29

tôi sẽ đi cho việc này:

public Guid ItemId 
{ 
    get; 
    private set; // can omit as of C# 6 
} 

public TransactionItem() 
{ 
    this.ItemId = Guid.Empty; 
} 

Tất nhiên, nó sẽ mở cho thiết trong lớp này, nhưng kể từ khi bạn đang viết nó, tôi hy vọng bạn có tinh thần để không phá vỡ ý định của riêng bạn ..

Theo tôi, những thứ như thuộc tính chỉ đọc, hầu hết là quan trọng khi nhìn từ bên ngoài. Từ bên trong, nó không thực sự quan trọng nó là gì, nguyên nhân ở đó, bạn là Vua =)

+0

+1 rất nhiều người không nhận ra đạo cụ có thể có phạm vi khác nhau – annakata

+1

Điều này giống như cách tôi sẽ đi! Cảm ơn bạn! Đã được nhiều hơn hoặc ít tò mò để xem nếu nó có thể được thực hiện mà không có một "bộ". – mattruma

+0

mở cửa một ngôi nhà không có cửa là khá khó khăn ...: p – Svish

2

Bạn có thể sử dụng từ khóa readonly

public readonly Guid ItemId; 

public TransactionItem() 
{ 
    this.ItemId = Guid.Empty; 
} 
+0

@Jakub, Làm ruộng anh em không tin là một cái gì đó bạn không nên làm trừ khi bạn * hoàn toàn * cần phải: http://csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx – LukeH

2

Tôi sợ câu hỏi của bạn không phải là rất rõ ràng - nhưng nếu không có một setter tài sản quy định, sau đó bạn chắc chắn có thể không gọi nó.

Bạn có thực sự sau một thuộc tính chỉ đọc được tự động triển khai, cho phép đặt ngay bên trong hàm tạo không? Nếu vậy, tôi e rằng không có sẵn, nhiều như tôi muốn.

Chỉ cần để mở rộng trên những gì tôi có nghĩa là, tôi muốn như để có thể làm: "làm cho một tài sản như một lĩnh vực readonly"

// Not valid in C# - yet! 
public class Foo 
{ 
    // Autogenerated field would be readonly in IL. 
    public string Name { get; readonly set; } 

    public Foo (string name) 
    { 
     this.Name = name; 
    } 

    public void Bar() 
    { 
     // This would be invalid 
     this.Name = "No!"; 
    } 
} 

Về cơ bản nó sẽ là

+0

Tôi không nghĩ rằng tôi đã nói đúng cách ... nhưng những gì bạn đang nói là chính xác. Chỉ cần cố gắng để tiết kiệm một số đánh máy ... và tò mò trên đầu trang của nó. – mattruma

+0

Không sao cả.Tôi đã chỉnh sửa câu trả lời để cho thấy những gì tôi muốn có thể làm - Tôi tin rằng đó là những gì bạn muốn. –

0

Sử dụng công cụ đặt riêng tư hoặc đặt trường sao lưu?
(Nhưng, bạn phải đảm bảo rằng tên của trường sao lưu có thể được xác định dựa trên tên thuộc tính.
Ví dụ bằng cách đảm bảo rằng trường sao lưu của bạn luôn có cùng tên với tên thuộc tính, nhưng được đặt trước bằng dấu gạch dưới; chẳng hạn như NHibernate bằng cách sử dụng các chiến lược truy cập của nó).

4

Nếu bạn chỉ cần thuộc tính ItemId để chỉ đọc cho người dùng bên ngoài lớp học, thì câu trả lời của Svish là con đường để đi.

Nếu bạn cần ItemId được read-only trong lớp đó sau đó bạn sẽ cần phải làm một cái gì đó như thế này:

private readonly Guid _ItemId 
public Guid ItemId 
{ 
    get { return _ItemId; } 
} 

public TransactionItem() 
{ 
    _ItemId = Guid.Empty; 
} 
+0

Một giải pháp tốt hơn nhiều so với câu trả lời được chấp nhận –

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