Làm thế nào để sử dụng Biến toàn cục trong C #?


101

Làm cách nào để khai báo một biến để mọi lớp (* .cs) có thể truy cập nội dung của nó mà không cần tham chiếu phiên bản?

Câu trả lời:


122

Trong C#bạn không thể định nghĩa các biến toàn cục thực sự (theo nghĩa là chúng không thuộc bất kỳ lớp nào).

Điều này đang được nói, cách tiếp cận đơn giản nhất mà tôi biết để bắt chước tính năng này bao gồm sử dụng static class, như sau:

public static class Globals
{
    public const Int32 BUFFER_SIZE = 512; // Unmodifiable
    public static String FILE_NAME = "Output.txt"; // Modifiable
    public static readonly String CODE_PREFIX = "US-"; // Unmodifiable
}

Sau đó, bạn có thể truy xuất các giá trị đã xác định ở bất kỳ đâu trong mã của mình (miễn là nó là một phần giống nhau namespace):

String code = Globals.CODE_PREFIX + value.ToString();

Để đối phó với các không gian tên khác nhau, bạn có thể:

  • khai báo Globalslớp mà không bao gồm nó vào một lớp cụ thể namespace(để nó sẽ được đặt trong không gian tên ứng dụng toàn cầu);
  • chèn chỉ thị sử dụng thích hợp để lấy các biến từ một biến khác namespace.

@Zarathos có phải lớp cũng phải tĩnh không?
kosnkov

4
Nó không cần thiết nhưng tôi không hiểu tại sao bạn nên khởi tạo nó.
Tommaso Belluzzo

Nếu bạn phải nhanh chóng xác định mỗi của nó không phải là "toàn cầu" nữa, không nằm trong trạng thái ứng dụng
Viking

Xin chào, sẽ có gì khác biệt nếu tôi không nhập từ khóa static vào lớp? Tôi chỉ đặt chuỗi FILE_NAME tĩnh, tôi đã thử và nó vẫn hoạt động với tôi.
Tomer Cahal

1
Nếu không có thuộc tính static, lớp của bạn sẽ có thể khởi tạo được (Globals g = new Globals ()). Nó không làm thay đổi hành vi của các biến tĩnh được khai báo bên trong, nhưng nó trông không thực sự hữu ích.
Tommaso Belluzzo

74

Không có cái gọi là biến toàn cục trong C #. Giai đoạn = Stage.

Bạn có thể có các thành viên tĩnh nếu bạn muốn:

public static class MyStaticValues
{
   public static bool MyStaticBool {get;set;}
}

Trong khi tôi đồng ý, bạn có thể vui lòng mở rộng lý do tại sao không có cái gọi là biến toàn cục trong C # không? Tôi đang cố gắng nghĩ ra một lý do chính đáng tại sao staticví dụ mà bạn đã cung cấp không thực sự được coi là một var toàn cầu.
cregox

3
@cawas bởi vì chính khái niệm về một "biến toàn cục" (treo lơ lửng, lơ lửng, không thuộc bất kỳ lớp nào) đi ngược lại bản chất của OOP. và C # là hướng đối tượng nghiêm ngặt.
Federico Berasategui

Vâng, đó là tất cả các khái niệm mà tôi đồng ý. Nhưng bằng cách tạo thành viên tĩnh đó, bạn vừa tạo một loại var toàn cầu. Điều đó khác với var toàn cục mà bạn nói không tồn tại như thế nào? Tôi muốn xem một ví dụ thực tế.
cregox

1
Tôi có cảm giác như bạn đang trốn tránh câu hỏi của tôi hoặc tôi không rõ. Nhưng tôi đã trả lời nó rồi. Tại đây: stackoverflow.com/a/20010543/274502
cregox

7
Bây giờ tôi nhận ra ý của tôi là các thành viên tĩnh là các vars toàn cầu về mặt khái niệm và thực tế (ngoại trừ có thể đối với thứ đống đó , điều này chỉ tạo ra sự khác biệt trừ khi bạn đang viết mã không an toàn hoặc thực hiện một số loại tương tác nặng với mã không được quản lý ). Vì vậy, tôi không biết tại sao mọi người lại nói " không có cái gọi là biến toàn cục trong csharp ". Nó làm tôi bối rối rất nhiều.
cregox

23

Trước tiên, hãy kiểm tra xem bạn có thực sự cần một biến toàn cục thay vì sử dụng nó một cách trắng trợn mà không xem xét đến kiến ​​trúc phần mềm của bạn hay không.

Giả sử nó vượt qua bài kiểm tra. Tùy thuộc vào cách sử dụng, Globals có thể khó gỡ lỗi với điều kiện chủng tộc và nhiều "điều tồi tệ" khác, tốt nhất hãy tiếp cận chúng từ một góc độ mà bạn đã sẵn sàng để xử lý những điều tồi tệ đó. Vì thế,

  1. Gói tất cả các biến Toàn cục như vậy vào một staticlớp duy nhất (để dễ quản lý).
  2. Có Thuộc tính thay vì các trường (= 'biến'). Bằng cách này, bạn có một số cơ chế để giải quyết bất kỳ vấn đề nào với việc ghi đồng thời lên Globals trong tương lai.

Đề cương cơ bản cho một lớp học như vậy sẽ là:

public class Globals
{
    private static bool _expired;
    public static bool Expired 
    {
        get
        {
            // Reads are usually simple
            return _expired;
        }
        set
        {
            // You can add logic here for race conditions,
            // or other measurements
            _expired = value;
        }
    }
    // Perhaps extend this to have Read-Modify-Write static methods
    // for data integrity during concurrency? Situational.
}

Sử dụng từ các lớp khác (trong cùng một không gian tên)

// Read
bool areWeAlive = Globals.Expired;

// Write
// past deadline
Globals.Expired = true;

4

Một tính năng hữu ích cho việc này là using static

Như những người khác đã nói, bạn phải tạo một lớp cho toàn cầu của mình:

public static class Globals {
    public const float PI = 3.14;
}

Nhưng bạn có thể nhập nó như thế này để không còn viết tên lớp trước các thuộc tính tĩnh của nó:

using static Globals;
[...]
Console.WriteLine("Pi is " + PI);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.