Merge pull request #3692 from lateralusX/jlorenss/win-api-family-support-libmono
[mono.git] / mcs / class / corlib / System / WeakReference_T.cs
1 //
2 // WeakReference_T.cs
3 //
4 // Author:
5 //       Martin Baulig <martin.baulig@xamarin.com>
6 //
7 // Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 // THE SOFTWARE.
26
27 using System.Runtime.Serialization;
28 using System.Runtime.InteropServices;
29
30 namespace System {
31         [SerializableAttribute]
32         public sealed class WeakReference<T> : ISerializable 
33                 where T : class
34         {
35                 GCHandle handle;
36                 bool trackResurrection;
37
38                 public WeakReference (T target)
39                         : this (target, false)
40                 {
41                 }
42
43                 public WeakReference (T target, bool trackResurrection)
44                 {
45                         this.trackResurrection = trackResurrection;
46                         var handleType = trackResurrection ? GCHandleType.WeakTrackResurrection : GCHandleType.Weak;
47                         handle = GCHandle.Alloc (target, handleType);
48                 }
49
50                 WeakReference (SerializationInfo info, StreamingContext context)
51                 {
52                         if (info == null)
53                                 throw new ArgumentNullException ("info");
54                         
55                         trackResurrection = info.GetBoolean ("TrackResurrection");
56                         var target = info.GetValue ("TrackedObject", typeof (T));
57
58                         var handleType = trackResurrection ? GCHandleType.WeakTrackResurrection : GCHandleType.Weak;
59                         handle = GCHandle.Alloc (target, handleType);
60                 }
61
62                 public void GetObjectData (SerializationInfo info, StreamingContext context)
63                 {
64                         if (info == null)
65                                 throw new ArgumentNullException ("info");
66                         
67                         info.AddValue ("TrackResurrection", trackResurrection);
68
69                         if (handle.IsAllocated)
70                                 info.AddValue ("TrackedObject", handle.Target);
71                         else
72                                 info.AddValue ("TrackedObject", null);
73                 }
74
75                 public void SetTarget (T target)
76                 {
77                         handle.Target = target;
78                 }
79
80                 public bool TryGetTarget (out T target)
81                 {
82                         if (!handle.IsAllocated) {
83                                 target = null;
84                                 return false;
85                         }
86
87                         target = (T)handle.Target;
88                         return target != null;
89                 }
90
91                 //Methods
92                 ~WeakReference ()
93                 {
94                         handle.Free ();
95                 }
96         }
97 }