2008-11-17 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mcs / class / corlib / System.Reflection / MonoField.cs
index 986be089ddc79db1c793ed359d0c4239ec70d7e5..c061f639665642e89bb793ea20a5854f0894fd15 100644 (file)
@@ -36,10 +36,12 @@ using System;
 using System.Globalization;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
 
 namespace System.Reflection {
-       
-       internal class MonoField : FieldInfo {
+
+       [Serializable]
+       internal class MonoField : FieldInfo, ISerializable {
                internal IntPtr klass;
                internal RuntimeFieldHandle fhandle;
                string name;
@@ -101,6 +103,10 @@ namespace System.Reflection {
 
                public override object GetValue (object obj)
                {
+                       if (!IsStatic && obj == null)
+                               throw new TargetException ("Non-static field requires a target");
+                       if (!IsLiteral)
+                               CheckGeneric ();
                        return GetValueInternal (obj);
                }
 
@@ -114,36 +120,50 @@ namespace System.Reflection {
                public override void SetValue (object obj, object val, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
                {
                        if (!IsStatic && obj == null)
-                               throw new ArgumentNullException ("obj");
+                               throw new TargetException ("Non-static field requires a target");
+                       if (IsLiteral)
+                               throw new FieldAccessException ("Cannot set a constant field");
                        if (binder == null)
                                binder = Binder.DefaultBinder;
+                       CheckGeneric ();
                        if (val != null) {
-                               val = binder.ChangeType (val, type, culture);
-                               if (val == null)
-                                       throw new ArgumentException ("Object type cannot be converted to target type.", "val");
+                               object newVal;
+                               newVal = binder.ChangeType (val, type, culture);
+                               if (newVal == null)
+                                       throw new ArgumentException ("Object type " + val.GetType() + " cannot be converted to target type: " + type, "val");
+                               val = newVal;
                        }
                        SetValueInternal (this, obj, val);
                }
-
-#if NET_2_0 || BOOTSTRAP_NET_2_0
-               [MonoTODO]
-               public override Type[] OptionalCustomModifiers {
-                       get {
-                               throw new NotImplementedException ();
-                       }
+               
+               internal MonoField Clone (string newName)
+               {
+                       MonoField field = new MonoField ();
+                       field.name = newName;
+                       field.type = type;
+                       field.attrs = attrs;
+                       field.klass = klass;
+                       field.fhandle = fhandle;
+                       return field;
                }
 
-               [MonoTODO]
-               public override Type[] RequiredCustomModifiers {
-                       get {
-                               throw new NotImplementedException ();
-                       }
+               // ISerializable
+               public void GetObjectData (SerializationInfo info, StreamingContext context) 
+               {
+                       MemberInfoSerializationHolder.Serialize (info, Name, ReflectedType,
+                               ToString(), MemberTypes.Field);
                }
-#endif
 
-#if NET_2_0 || BOOTSTRAP_NET_2_0
+#if NET_2_0
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public override extern FieldInfo Mono_GetGenericFieldDefinition ();
+               public override extern object GetRawConstantValue ();
+#endif
+
+               void CheckGeneric () {
+#if NET_2_0
+                       if (DeclaringType.ContainsGenericParameters)
+                               throw new InvalidOperationException ("Late bound operations cannot be performed on fields with types for which Type.ContainsGenericParameters is true.");
 #endif
+           }
        }
 }