const
và readonly
tương tự nhau, nhưng chúng không hoàn toàn giống nhau.
Một const
lĩnh vực là một hằng số thời gian biên dịch, có nghĩa là giá trị mà có thể được tính tại thời gian biên dịch. Một readonly
trường cho phép các kịch bản bổ sung trong đó một số mã phải được chạy trong khi xây dựng loại. Sau khi xây dựng, một readonly
lĩnh vực không thể thay đổi.
Chẳng hạn, const
các thành viên có thể được sử dụng để xác định các thành viên như:
struct Test
{
public const double Pi = 3.14;
public const int Zero = 0;
}
Vì các giá trị như 3.14 và 0 là hằng số thời gian biên dịch. Tuy nhiên, hãy xem xét trường hợp bạn xác định một loại và muốn cung cấp một số phiên bản pre-fab của loại đó. Ví dụ, bạn có thể muốn xác định lớp Màu và cung cấp "hằng số" cho các màu phổ biến như Đen, Trắng, v.v. Không thể làm điều này với các thành viên const, vì phía bên tay phải không phải là hằng số thời gian biên dịch. Người ta có thể làm điều này với các thành viên tĩnh thông thường:
public class Color
{
public static Color Black = new Color(0, 0, 0);
public static Color White = new Color(255, 255, 255);
public static Color Red = new Color(255, 0, 0);
public static Color Green = new Color(0, 255, 0);
public static Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}
Nhưng sau đó, không có gì để giữ một khách hàng của Color khỏi bị làm phiền với nó, có lẽ bằng cách hoán đổi các giá trị Đen và Trắng. Không cần phải nói, điều này sẽ gây ra sự bối rối cho các khách hàng khác của lớp Màu. Tính năng "chỉ đọc" giải quyết tình huống này.
Bằng cách đơn giản là giới thiệu readonly
từ khóa trong các khai báo, chúng tôi duy trì việc khởi tạo linh hoạt trong khi ngăn chặn mã máy khách khỏi bị lừa đảo.
public class Color
{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
public static readonly Color Red = new Color(255, 0, 0);
public static readonly Color Green = new Color(0, 255, 0);
public static readonly Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}
Thật thú vị khi lưu ý rằng các thành viên const luôn tĩnh, trong khi một thành viên chỉ đọc có thể là tĩnh hoặc không, giống như một trường thông thường.
Có thể sử dụng một từ khóa duy nhất cho hai mục đích này, nhưng điều này dẫn đến các vấn đề về phiên bản hoặc vấn đề về hiệu suất. Giả sử trong một khoảnh khắc chúng tôi đã sử dụng một từ khóa duy nhất cho (const) này và một nhà phát triển đã viết:
public class A
{
public static const C = 0;
}
và một nhà phát triển khác đã viết mã dựa trên A:
public class B
{
static void Main() => Console.WriteLine(A.C);
}
Bây giờ, mã được tạo có thể dựa vào thực tế rằng AC là hằng số thời gian biên dịch không? Tức là, việc sử dụng AC có thể được thay thế bằng giá trị 0 không? Nếu bạn nói "có" với điều này, thì điều đó có nghĩa là nhà phát triển của A không thể thay đổi cách khởi tạo AC - điều này ràng buộc tay của nhà phát triển A mà không được phép.
Nếu bạn nói "không" với câu hỏi này thì việc tối ưu hóa quan trọng sẽ bị bỏ qua. Có lẽ tác giả của A tích cực rằng AC sẽ luôn bằng không. Việc sử dụng cả const và readonly cho phép nhà phát triển của A chỉ định ý định. Điều này làm cho hành vi phiên bản tốt hơn và hiệu suất tốt hơn.
static readonly
: hãy thử sử dụng một const bên trongIEnumerator
nó sẽ kích hoạt một lỗi không đáng tin cậyyield
và bạn sẽ nhận được một "lỗi trình biên dịch nội bộ" đáng sợ . Tôi đã không kiểm tra mã bên ngoài Unity3D, nhưng tôi tin rằng đây là lỗi đơn hoặc .NET . Đây là một vấn đề c # tuy nhiên.