[runtime] Updates comments.
[mono.git] / mcs / class / corlib / System.Reflection / MonoField.cs
index 48247af850251151e837a4b4c50c320b4ddefa2c..117eea363fd520e7c1998c4aedd28d2f0f580a37 100644 (file)
 //
 
 using System;
+using System.Collections.Generic;
 using System.Globalization;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
 
 namespace System.Reflection {
-       
-       internal class MonoField : FieldInfo {
+
+       abstract class RuntimeFieldInfo : FieldInfo
+       {
+               internal BindingFlags BindingFlags {
+                       get {
+                               return 0;
+                       }
+               }
+       }
+
+       abstract class RtFieldInfo : RuntimeFieldInfo
+       {
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               internal extern object UnsafeGetValue (object obj);
+       }
+
+       [Serializable]
+       [StructLayout (LayoutKind.Sequential)]
+       internal class MonoField : RtFieldInfo, ISerializable {
                internal IntPtr klass;
                internal RuntimeFieldHandle fhandle;
                string name;
@@ -57,8 +76,13 @@ namespace System.Reflection {
                        }
                }
 
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               extern Type ResolveType ();
+
                public override Type FieldType { 
                        get {
+                               if (type == null)
+                                       type = ResolveType ();
                                return type;
                        }
                }
@@ -101,13 +125,23 @@ namespace System.Reflection {
 
                public override object GetValue (object obj)
                {
-                       if (!IsStatic && obj == null)
-                               throw new TargetException ("Non-static field requires a target");
+                       if (!IsStatic) {
+                               if (obj == null)
+                                       throw new TargetException ("Non-static field requires a target");
+                               if (!DeclaringType.IsAssignableFrom (obj.GetType ()))
+                                       throw new ArgumentException (string.Format (
+                                               "Field {0} defined on type {1} is not a field on the target object which is of type {2}.",
+                                               Name, DeclaringType, obj.GetType ()),
+                                               "obj");
+                       }
+                       
+                       if (!IsLiteral)
+                               CheckGeneric ();
                        return GetValueInternal (obj);
                }
 
                public override string ToString () {
-                       return String.Format ("{0} {1}", type, name);
+                       return String.Format ("{0} {1}", FieldType, name);
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -115,18 +149,23 @@ namespace System.Reflection {
 
                public override void SetValue (object obj, object val, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
                {
-                       if (!IsStatic && obj == null)
-                               throw new TargetException ("Non-static field requires a target");
+                       if (!IsStatic) {
+                               if (obj == null)
+                                       throw new TargetException ("Non-static field requires a target");
+                               if (!DeclaringType.IsAssignableFrom (obj.GetType ()))
+                                       throw new ArgumentException (string.Format (
+                                               "Field {0} defined on type {1} is not a field on the target object which is of type {2}.",
+                                               Name, DeclaringType, obj.GetType ()),
+                                               "obj");
+                       }
                        if (IsLiteral)
                                throw new FieldAccessException ("Cannot set a constant field");
                        if (binder == null)
-                               binder = Binder.DefaultBinder;
+                               binder = Type.DefaultBinder;
+                       CheckGeneric ();
                        if (val != null) {
-                               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;
+                               RuntimeType fieldType = (RuntimeType) FieldType;
+                               val = fieldType.CheckValue (val, binder, culture, invokeAttr);
                        }
                        SetValueInternal (this, obj, val);
                }
@@ -141,5 +180,24 @@ namespace System.Reflection {
                        field.fhandle = fhandle;
                        return field;
                }
+
+               // ISerializable
+               public void GetObjectData (SerializationInfo info, StreamingContext context) 
+               {
+                       MemberInfoSerializationHolder.Serialize (info, Name, ReflectedType,
+                               ToString(), MemberTypes.Field);
+               }
+
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               public override extern object GetRawConstantValue ();
+
+               public override IList<CustomAttributeData> GetCustomAttributesData () {
+                       return CustomAttributeData.GetCustomAttributes (this);
+               }
+
+               void CheckGeneric () {
+                       if (DeclaringType.ContainsGenericParameters)
+                               throw new InvalidOperationException ("Late bound operations cannot be performed on fields with types for which Type.ContainsGenericParameters is true.");
+           }
        }
 }