2011-10-09 15 views
18

Trường chỉ đọc phải được sử dụng khi bạn có biến được biết tại sự biến đổi đối tượng mà không được thay đổi sau đó.trường chỉ đọc làm mục tiêu từ các hàm tạo lớp con

Tuy nhiên, người ta không được phép chỉ định các trường chỉ đọc từ các nhà xây dựng của các lớp con. Điều này thậm chí không hoạt động nếu siêu lớp là trừu tượng.

Có ai có giải thích tốt về lý do tại sao điều này không phải là ý tưởng hay hoặc thiếu trong C# languange?

abstract class Super 
{ 
    protected readonly int Field; 
} 

class Sub : Super 
{ 
    public Sub() 
    { 
     this.Field = 5; //Not compileable 
    } 
} 

PS: Tất nhiên bạn cũng có thể đạt được kết quả tương tự bằng cách gán các trường chỉ đọc trong một hàm tạo được bảo vệ trong lớp cha.

+1

Ngoài ra lỗi trình biên dịch không chính xác: 'Lỗi 68 Một trường chỉ đọc không thể được gán cho (ngoại trừ trong hàm tạo hoặc biến khởi tạo biến)' – nicodemus13

Trả lời

12

Lý do duy nhất tôi có thể thấy cho điều này là bởi vì "nó chỉ được thiết kế theo cách đó", theo spec:

nhiệm vụ trực tiếp đến readonly lĩnh vực chỉ có thể xảy ra như là một phần của điều đó khai hoặc trong một hàm tạo thể hiện hoặc hàm tạo tĩnh trong lớp giống nhau .

Điểm được đọc là không thể thay đổi, nếu các lớp dẫn xuất có thể sửa đổi thì điều này sẽ không còn đúng và sẽ vi phạm đóng gói (bằng cách sửa đổi nội bộ của lớp khác).

+1

đúng. Nhưng nó vẫn không thích hợp cho các lớp trừu tượng? Có lẽ vì khả năng của nhiều lớp con. – philipshield

+2

Nó có thể là không phù hợp, và có lẽ chúng ta sẽ không bao giờ biết lý do chính xác cho quyết định thiết kế đó. –

+0

Tôi không thấy lý do tại sao nó không phù hợp với các lớp trừu tượng, vì chúng có thể có các hàm tạo nên các trường chỉ đọc sẽ hoạt động. – pauloya

10
public class Father 
{ 
    protected readonly Int32 field; 

    protected Father (Int32 field) 
    { 
     this.field = field; 
    } 
} 

public class Son : Father 
{ 
    public Son() : base(5) 
    { 

    } 
} 

Bạn có thể thử thay thế như thế này!

+0

Ồ, tôi không thấy! Đó có phải là bản chỉnh sửa không? – renatoargh

+0

Có Tôi đã đề cập rằng trong câu hỏi của tôi :) Ngoài ra, alexm đã đăng chính xác câu trả lời khoảng 10 phút trước. – philipshield

+2

Nó không phải là một chỉnh sửa, nhưng không bao giờ có! Đó là giải pháp gọn gàng – philipshield

0

Tôi cho rằng nguyên nhân chính là một phức tạp thêm cho mọi cài đặt ngôn ngữ .NET

cũng vậy, luôn luôn có một cách giải quyết đơn giản:

abstract class Super 
{ 
    protected readonly int Field; 

    protected Super(int field) 
    { 
      this.Field = field; 
    } 
} 


class Sub : Super { 
    public Sub():base(5) 
    { 
    } 

}

0

tôi sẽ mô hình này bằng một thuộc tính trừu tượng/ảo trong C#.

abstract class Super { 
    protected abstract int Field { get; } 
} 

class Sub : Super { 
    protected override int Field { get { return 5; } } 
} 

Theo tôi, giải pháp tốt hơn là có một hàm tạo bao gồm từng trường chỉ đọc như tham số. Đối với một vì trình biên dịch có thể nội tuyến này là tốt và cũng vì các giải pháp xây dựng sẽ trông như thế này trong lớp có nguồn gốc:

class Sub : Super { 
    public Sub() : base(5) { } // 5 what ?? -> need to check definition of super class constructor 
} 

Cũng có thể không hoạt động nếu bạn đã có một constructor mà phải mất một int đơn giá trị.

0

Tôi muốn sử dụng hàm tạo được bảo vệ trong siêu lớp (như đã đề cập bởi alexm), tiếp cận với các nhận xét xml. Điều này sẽ loại bỏ vấn đề mà DonAndre đã nói trong bình luận mã của anh ấy.