2013-02-07 40 views
12

Trong C# Tôi có một lớp generic:Biến thành viên tĩnh có phổ biến cho tất cả các C# chung instantiations không?

public class MyGeneric<ParameterClass> where ParameterClass: MyGenericParameterClass, new() { 
    public static int Variable; 
} 

Bây giờ trong C++ nếu tôi khởi tạo một lớp templated với các thông số khác nhau mỗi lớp hoàn chỉnh sẽ có được nó là của riêng Variable, vì vậy I just can't say

MyGeneric.Variable = 1; // invalid in C++ 

trong C++, nhưng có vẻ như tôi có thể làm như vậy trong C#.

Tôi muốn làm rõ ...

Nếu tôi có chung chung với biến thành viên tĩnh là biến được chia sẻ giữa tất cả các instantiations chung?

Trả lời

12

Section 25.1.4 of the ECMA C# Language specification

Một biến tĩnh trong một bản tuyên bố chung lớp được chia sẻ giữa tất cả các trường của cùng một loại được xây dựng khép kín (§26.5.2), nhưng là không được chia sẻ giữa các trường hợp khép kín khác nhau xây dựng loại. Các quy tắc này áp dụng bất kể loại biến tĩnh có liên quan đến bất kỳ thông số loại nào hay không.

Bạn có thể thấy bài blog này: Static fields in generic classes bởi Gus Perez

Bạn không thể làm điều đó trong C# là tốt.

MyGeneric.Variable = 1; 

Hãy xem ví dụ sau đây từ Đặc tả ngôn ngữ ECMA.

class C<V> 
{ 
    static int count = 0; 
    public C() 
    { 
     count++; 
    } 
    public static int Count 
    { 
     get { return count; } 
    } 
} 
class Application 
{ 
    static void Main() 
    { 
     C<int> x1 = new C<int>(); 
     Console.WriteLine(C<int>.Count); // Prints 1 
     C<double> x2 = new C<double>(); 
     Console.WriteLine(C<double>.Count); // Prints 1 
     Console.WriteLine(C<int>.Count); // Prints 1 
     C<int> x3 = new C<int>(); 
     Console.WriteLine(C<int>.Count); // Prints 2 
    } 
} 
2

Không, nó không được chia sẻ.

Mỗi lớp MyGeneric<T> sẽ giải quyết thành loại thời gian chạy khác nhau, cho mỗi khả năng là T.

Vui lòng kiểm tra để đảm bảo rằng không có lớp học phi chung chung MyGeneric với thành viên tĩnh Variable.

2

Không, không phải. Các loại chung có thể là "mở" hoặc "đã đóng". Kiểu mở là một kiểu như List<T> trong đó thông số kiểu không được xác định; List<int> là loại đóng.

Về cơ bản, loại mở không được coi là "Loại" phù hợp theo thời gian chạy - chỉ các phiên bản đã đóng là các loại thực. Vì vậy, MyGeneric<int>MyGeneric<string> là hai loại hoàn toàn khác nhau và do đó có trường hợp riêng của biến tĩnh.

Điều này được thực hiện rõ ràng hơn bởi thực tế là bạn không thể gọi thành viên tĩnh theo cách bạn đề xuất: MyGeneric.Variable sẽ không biên dịch trong C#.

console này mã ứng dụng minh họa nó khá đơn giản:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Test<int>.i = 2; 
     Test<string>.i = 8; 

     Console.WriteLine(Test<int>.i); // would write "8" if the fields were shared 
     Console.WriteLine(Test<string>.i); 
     // Console.WriteLine(Test.i); // does not compile 
     // Console.WriteLine(Test<>.i); // does not compile 
    } 
} 

class Test<T> 
{ 
    public static int i; 
} 
6
MyGeneric<MyClass>.Variable 
MyGeneric<MyOther>.Variable 

Hai là các biến tĩnh khác nhau đối xử như các lớp riêng biệt.

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