2013-03-30 46 views
5

Tôi đang cố tạo một lớp có giá trị a làm tham số trong hàm tạo của nó. Nó có một biến thành viên riêng để lưu trữ giá trị này. Giá trị không được thay đổi sau đó.Xây dựng lớp mà thuộc tính của chỉ có thể được thiết lập trong hàm tạo, nhưng có được ở đâu không?

Đây là những gì tôi có, nó hoạt động nhưng tôi không nghĩ rằng đó là giải pháp tốt nhất hiện có:

internal class Foo 
{ 
    private int a; 
    public int A 
    { 
     get 
     { 
      return this.a; 
     } 
    } 

    public Foo(int a) 
    { 
     this.a = a; 
    } 
} 

Vì vậy, bằng cách này bạn không thể truy cập a từ bên ngoài của lớp, và A -property chỉ có một phương thức get. Tuy nhiên, bạn vẫn có thể thay đổi a từ bên trong lớp và sử dụng thuộc tính chỉ trả về một biến và không có gì khác cảm thấy ngu ngốc.

Tôi có làm điều này đúng không, hoặc có cách nào để cải thiện mã của tôi/cách thích hợp hơn để thực hiện việc này không?

Trả lời

6

Ngoài ra, hãy khai báo trường riêng tư của bạn readonly và bạn đang ở đó!

public class Foo 
{ 
    public Foo(int bar) 
    { 
     this.bar = bar; 
    } 

    public int Bar 
    { 
     get 
     { 
      return bar; 
     } 
    } 
    private readonly int bar; 
} 
+1

Ahh tốt đẹp, không biết 'readonly', tôi đã thử sử dụng' const' nhưng đã từ bỏ vì nó không thể được đặt trong hàm tạo. Nice :) –

0
internal class Foo 
{ 
    private readonly int _a; 
    public int A 
    { 
     get 
     { 
      return _a; 
     } 
    } 

    public Foo(int a) 
    { 
     _a = a; 
    } 
} 

này nên làm điều đó.

+2

Điều này sẽ không làm những gì OP muốn. Bạn vẫn có thể thay đổi 'A' từ bên trong lớp vì nó được đặt thành riêng tư. OP chỉ muốn thiết lập nó một lần từ hàm tạo và do đó, 'readonly' là bắt buộc. – keyboardP

+0

Có vẻ thú vị, nhưng bạn vẫn có thể thay đổi 'A' từ bên trong lớp học. Bạn có thể sử dụng 'readonly' với các thuộc tính không? –

+0

Q của bạn hơi mơ hồ. Như đã đề cập bởi @stakx, chỉ cần thực hiện 'readonly' nếu bạn cần gán giá trị một lần hoặc sử dụng 'private set' nếu bạn không muốn để lộ ra ngoài lớp. –

4

"Trong C# 6 trở lên, you can initialize auto-implemented properties similarly to fields". Cũng giống như bạn có thể khởi tạo một trường readonly trong một hàm tạo, bạn có thể khởi tạo thuộc tính tự động chỉ được tạo trong một hàm tạo. Như vậy, sau giờ biên dịch:

public class Class1 
{ 
    public int A { get; } 
    public Class1(int a) 
    { 
     A = a; 
    } 
} 

... và sau đây mang lại một lỗi:

public class Class1 
{ 
    public int A { get; } 
    public Class1(int a) 
    { 
     A = a; 
    } 
    public void Mutate() 
    { 
     // Class1.cs(11,9,11,10): error CS0200: Property or indexer 'Class1.A' cannot be assigned to -- it is read only 
     A++; 
    } 
} 

tôi thích nó-bạn nhận được terseness khởi tạo lĩnh vực với giao diện/OOP thân thiện với bất động sản.