2002-06-27 Martin Baulig <martin@gnome.org>
[mono.git] / mcs / class / corlib / System / WeakReference.cs
1 //
2 // System.WeakReference.cs
3 //
4 // Author:
5 //   Ajay kumar Dwivedi (adwiv@yahoo.com)
6 //
7
8 using System.Runtime.Serialization;
9 using System.Runtime.InteropServices;
10
11 namespace System
12 {
13         /// <summary>
14         /// Summary description for WeakReference.
15         /// </summary>
16         [Serializable]
17         public class WeakReference : ISerializable
18         {
19                 //Fields
20                 private bool isLongReference;
21                 private GCHandle gcHandle;
22
23                 // Helper method for constructors
24                 //Should not be called from any other method.
25                 private void AllocateHandle(Object target)
26                 {
27                         if(this.isLongReference)
28                         {
29                                 this.gcHandle = GCHandle.Alloc(target, GCHandleType.WeakTrackResurrection);
30                         }
31                         else
32                         {
33                                 this.gcHandle = GCHandle.Alloc(target, GCHandleType.Weak);
34                         }
35                 }               
36                 
37                 
38                 //Constructors
39                 public WeakReference(object target)
40                         : this(target,false)
41                 {}
42
43                 
44                 public WeakReference(object target, bool trackResurrection)
45                 {
46                         this.isLongReference = trackResurrection;
47                         AllocateHandle(target);
48                 }
49
50                 
51                 protected WeakReference(SerializationInfo info, StreamingContext context)
52                 {
53                         if (info == null)
54                                 throw new ArgumentNullException ("info");
55
56                         this.isLongReference = info.GetBoolean("IsLongReference");
57                         //TODO: How to load the exact type?
58                         //Does that matter? No idea :(
59                         Object target = info.GetValue("TargetObject",typeof(System.Object));
60
61                         AllocateHandle(target);
62                 }
63
64                 
65                 // Properties
66                 public virtual bool IsAlive 
67                 {
68                         get
69                         {
70                                 //Target property takes care of the exception
71                                 return (Target != null);                
72                         }
73                 }
74
75                 public virtual object Target 
76                 {
77                         get
78                         {
79                                 //Exception is thrown by gcHandle's Target
80                                 return this.gcHandle.Target;
81                         }
82                         set
83                         {
84                                 this.gcHandle.Target = value;
85                         }
86                 }
87
88                 public virtual bool TrackResurrection 
89                 {
90                         get
91                         {
92                                 return this.isLongReference;
93                         }
94                 }
95
96                 //Methods
97                 ~WeakReference()
98                 {
99                         gcHandle.Free();
100                 }
101
102                 //TODO
103                 public virtual void GetObjectData(SerializationInfo info,StreamingContext context)
104                 {
105                         if (info == null)
106                                 throw new ArgumentNullException ("info");
107
108                         info.AddValue("IsLongReference",this.isLongReference);
109                         try
110                         {
111                                 info.AddValue("TargetObject",Target);
112                         }
113                         catch(Exception)
114                         {
115                                 info.AddValue("TargetObject",null);
116                         }
117                 }
118         }
119 }