Fix bugs in sizing TableLayoutPanel (Xamarin bug 18638)
[mono.git] / mcs / class / System.ComponentModel.Composition / src / ComponentModel / System / Lazy.cs
1 // -----------------------------------------------------------------------\r
2 // Copyright (c) Microsoft Corporation.  All rights reserved.\r
3 // -----------------------------------------------------------------------\r
4 #if !CLR40\r
5 using System;\r
6 using System.Collections.Generic;\r
7 using System.Linq;\r
8 using System.Text;\r
9 using System.Threading;\r
10 using Microsoft.Internal;\r
11 \r
12 namespace System\r
13 {\r
14     public class Lazy<T>\r
15     {\r
16         private T _value = default(T);\r
17         private volatile bool _isValueCreated = false;\r
18         private Func<T> _valueFactory = null;\r
19         private object _lock;\r
20 \r
21         public Lazy()\r
22             : this(() => Activator.CreateInstance<T>())\r
23         {\r
24         }\r
25 \r
26         public Lazy(bool isThreadSafe)\r
27             : this(() => Activator.CreateInstance<T>(), isThreadSafe)\r
28         {\r
29         }\r
30 \r
31         public Lazy(Func<T> valueFactory):\r
32             this(valueFactory, true)\r
33         {\r
34         }\r
35 \r
36         public Lazy(Func<T> valueFactory, bool isThreadSafe)\r
37         {\r
38             Requires.NotNull(valueFactory, "valueFactory");\r
39             if(isThreadSafe)\r
40             {\r
41                 this._lock = new object();\r
42             }\r
43 \r
44             this._valueFactory = valueFactory;\r
45         }\r
46 \r
47 \r
48         public T Value\r
49         {\r
50             get\r
51             {\r
52                 if (!this._isValueCreated)\r
53                 {\r
54                     if(this._lock != null)\r
55                     {\r
56                         Monitor.Enter(this._lock);\r
57                     }\r
58 \r
59                     try\r
60                     {\r
61                         T value = this._valueFactory.Invoke();\r
62                         this._valueFactory = null;\r
63                         Thread.MemoryBarrier();\r
64                         this._value = value;\r
65                         this._isValueCreated = true;\r
66                     }\r
67                     finally\r
68                     {\r
69                         if(this._lock != null)\r
70                         {\r
71                             Monitor.Exit(this._lock);\r
72                         }\r
73                     }\r
74                 }\r
75                 return this._value;\r
76             }\r
77         }\r
78     }\r
79 }\r
80 #endif\r