2011-07-29 35 views
13

Tôi đã nhẹ ngạc nhiên khi trình biên dịch phàn nàn về điều này:Không thể đọc một const trong một cá thể lớp?

public class UsefulClass 
{ 
    public const String RatingName = @"Ratings\rating"; 
} 

public class OtherClass 
{ 
    public void SomeFunc() 
    { 
     UsefulClass useful = new UsefulClass(); 
     String rating = useful.RatingName; 
    } 
} 

Compiler nói, "thành viên tĩnh không thể truy cập với một tài liệu tham khảo ví dụ; đủ điều kiện nó với một loại tên thay vì"

isn này 't một vấn đề, String rating = UsefulClass.RatingName; hoạt động tốt. Tôi chỉ tò mò những suy nghĩ đằng sau điều này là gì? Tôi có một thể hiện của một lớp công cộng với một hằng số công khai trên đó, tại sao tôi không thể lấy dữ liệu theo cách này?

+2

Thiết kế ngôn ngữ kinh khủng vi phạm nghiêm trọng http://en.wikipedia.org/wiki/Uniform_access_principle ... không có lý do gì cho nó và họ có thể khắc phục nó, không ảnh hưởng đến mã hiện tại, trong giây lát. –

Trả lời

25

Vì hằng số không phải là thành viên cá thể; chúng được liên kết tĩnh với các kiểu tương ứng của chúng. Trong cùng một cách bạn không thể gọi các phương thức tĩnh bằng cách sử dụng các cá thể, bạn không thể truy cập các hằng số lớp bằng cách sử dụng các cá thể.

Nếu bạn cần để có được một hằng số tắt một trường hợp mà không biết loại đầu tiên của nó, tôi giả sử bạn có thể làm điều đó với sự phản ánh dựa trên loại của nó.

Nếu bạn đang cố gắng thêm thành viên không thể sửa đổi nhưng liên quan đến các phiên bản, bạn có thể chỉ muốn các trường hoặc thuộc tính chỉ đọc.

+2

Bạn cũng có thể quấn các hằng số trong một getter. –

+1

@BoltClock, tôi đã thử kiểm tra điểm của bạn bằng 'String something = this.RatingName' bên trong UsefulClass và gặp lỗi tương tự, phù hợp với câu trả lời của bạn. Tôi đã luôn luôn giả định 'String cái gì đó = RatingName' là nhìn vào dụ, nhưng tôi thấy bây giờ nó sử dụng mô tả Class.Variable của một tĩnh. – TomDestry

+0

@TomDestry: Đúng vậy, giống như cách bạn gọi các phương thức tĩnh của lớp bằng cách sử dụng 'StaticMethod()' thay vì 'this.StaticMethod()'. – BoltClock

10

Một "biến" được đánh dấu const là một cấu trúc thời gian biên dịch, không phải là thành viên thể hiện. Bạn có thể truy cập vào nó như bạn sẽ một biến tĩnh:

public void SomeFunc() 
{ 
    UsefulClass useful = new UsefulClass(); 
    String rating = UsefulClass.RatingName; // Access as if static 
} 

Điều đó đang được nói, tôi sẽ đích thân quấn này thành một tài sản nếu nó có nghĩa là để được sử dụng như bạn mô tả, như vậy:

public class UsefulClass 
{ 
    private const string ratingName = @"Ratings\rating"; 

    public string RatingName { get { return ratingName; } } 
} 

Điều này sẽ làm cho cú pháp của bạn hoạt động, nhưng cũng là một thiết kế tốt hơn, IMO, vì nó không phơi bày các hằng số của bạn một cách công khai.

+0

Tôi không đồng ý với kế hoạch gói nó trong một getter (đó là sai), nhưng bạn đã cung cấp câu trả lời đúng ban đầu, ít nhất (vì vậy tôi upvoted bạn). –

+0

@NoonSilk, Tại sao nó sai? – TomDestry

+0

@Noon Silk: Tôi khuyên rằng điều này là đúng và không sai, ** nếu dữ liệu phải được liên kết với một cá thể ** (RatingName). Đây là cách OP trình bày nó, trong trường hợp đó, nó là dữ liệu mức cá thể, và nên được bọc trong một thuộc tính (ngay cả khi nó luôn luôn trả về một hằng số). Điều đó làm cho bản chất "liên tục" trở thành một chi tiết thực hiện của chính nó. –

-2

Vì const trong C# là ngầm của loại tĩnh. Và như các thành viên tĩnh có thể được truy cập chỉ trên thành viên lớp và không phải là ví dụ, const không thể quá.

+1

Bạn trả lời như thế nào về các câu trả lời đã được cung cấp? –

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