2010-01-15 34 views
20

Tôi muốn biết liệu C# có được tự động thực hiện các thuộc tính, như public static T Prop { get; set; }, có an toàn hay không. Cảm ơn!C# có được tự động triển khai các thuộc tính tĩnh an toàn không?

+0

Bạn phải xác định chính xác ý nghĩa của "thread an toàn" trong trường hợp cụ thể này, trước tiên. –

+0

Bởi chủ đề an toàn Tôi có nghĩa là, nếu tôi viết giá trị trong một chủ đề, và một chủ đề cố gắng để đọc nó, có thể các chủ đề thứ hai có được một giá trị sai. –

Trả lời

15

Dường như không. Đây là sự giải mã với Reflector:

private static string Test 
{ 
    [CompilerGenerated] 
    get 
    { 
     return <Test>k__BackingField; 
    } 
    [CompilerGenerated] 
    set 
    { 
     <Test>k__BackingField = value; 
    } 
} 
+0

Đó là loại sai. Mô hình bộ nhớ của .NET đảm bảo rằng việc ghi vào chúng sẽ là nguyên tử và được xem bởi tất cả các luồng, ít nhất là cho .NET Framework thông thường, và nếu chúng không phải là ảo, chúng sẽ luôn được inlined.Cả hai đều là các chi tiết thực hiện của khung làm việc .NET và không được bảo đảm bởi spec. –

+0

er Tôi có nghĩa là decompilation là chính xác, nhưng cách chúng được thực hiện đảm bảo atomicity, ít nhất là cho số nguyên và các loại tài liệu tham khảo (với báo trước rõ ràng rằng atomicity! = Thread an toàn). Đối với longs/đôi/structs/etc, bạn đang trên một mình, mặc dù. –

+3

Đặc tả đảm bảo rằng những thứ như 'Int32',' float' và tham chiếu là ** nguyên tử **. Nó không thực hiện nhiều đảm bảo về khả năng hiển thị luồng/đăng ký bộ nhớ đệm, v.v. –

2

Không, chúng không an toàn. Các thuộc tính tĩnh cũng dễ bị tổn thương như các trường tĩnh là các vấn đề tương tranh.

4

Tôi không tin như vậy. Tôi tin rằng chúng chỉ là đường tổng hợp cho:

private static T _prop; 
public static T Prop 
{ 
    get { return _prop; } 
    set { _prop = value; } 
} 
5

No. Bạn phải quấn chúng trong cơ chế khóa ren.

object _lock = new object(); 
public static Main(string[] args) 
{ 
    lock(_lock) 
    { 
     Prop = new T(); 
    } 


    T val = null; 
    lock(_lock) 
    { 
     val = Prop; 
    } 
} 
+1

Prop là gì? T là gì? –

+4

Prop và T là từ câu hỏi. – Amy

4

Không có đồng bộ hóa được cung cấp với các thuộc tính tự động, bao gồm các thuộc tính tĩnh.

Nếu bạn cần an toàn toàn bộ chuỗi, bạn sẽ muốn sử dụng các thuộc tính của riêng bạn với trường sao lưu và tự xử lý đồng bộ hóa.

4

Để hoàn thành, các sự kiện giống như trường do có tính năng an toàn chủ đề được tích hợp sẵn nhưng chúng đơn độc trong trường hợp này. Các thuộc tính được tự động thực hiện không có bất kỳ tính năng nào như vậy. Bạn có thể, tuy nhiên, làm điều gì đó như:

public static double SomeProp 
{ // ### NOT RECOMMENDED ### 
    [MethodImpl(MethodImplOptions.Synchronized)] get; 
    [MethodImpl(MethodImplOptions.Synchronized)] set; 
} 

Vấn đề ở đây là nó sẽ khóa Type, mà là một điều xấu . Tôi sẽ thực hiện đồng bộ hóa của riêng tôi cho điều này, cá nhân.

+1

"xấu" vì các lý do "sắp xếp theo lưu lượng", nơi khóa Loại chảy máu vào các appdomain bị cô lập khác trong cùng một quá trình ... – x0n

+1

Chỉ đủ xấu với một sự thật về miền ứng dụng. –

47

Mục 10.7.4 của đặc tả trạng thái C#:

Khi một tài sản được quy định như một tài sản tự động thực hiện, một ẩn lĩnh vực ủng hộ tự động là sẵn cho tài sản, và accessors là được triển khai để đọc từ và ghi vào trường sao lưu đó. Các ví dụ sau:

public class Point { 
    public int X { get; set; } // automatically implemented 
    public int Y { get; set; } // automatically implemented 
} 

là tương đương với việc kê khai như sau:

public class Point { 
    private int x; 
    private int y; 
    public int X { get { return x; } set { x = value; } } 
    public int Y { get { return y; } set { y = value; } } 
} 

Đó là những gì chúng tôi hứa, và đó là những gì bạn nhận được. Điểm của thuộc tính tự động là làm điều cơ bản, đơn giản, rẻ nhất; nếu bạn muốn làm một cái gì đó fancier thì bạn nên viết một tài sản "thực sự".

+7

Đã bỏ phiếu cho bạn để tham khảo thông số C# thực tế. –

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