summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Reflection/MdFieldInfo.cs
blob: 9645b7fef282786bed7c2c99ad2561fa3805c64e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Diagnostics;
using System.Globalization;
using System.Runtime.Serialization;
using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;

namespace System.Reflection
{
    internal sealed unsafe class MdFieldInfo : RuntimeFieldInfo, ISerializable
    {
        #region Private Data Members
        private int m_tkField;
        private string m_name;
        private RuntimeType m_fieldType;
        private FieldAttributes m_fieldAttributes;
        #endregion

        #region Constructor
        internal MdFieldInfo(
        int tkField, FieldAttributes fieldAttributes, RuntimeTypeHandle declaringTypeHandle, RuntimeTypeCache reflectedTypeCache, BindingFlags bindingFlags)
            : base(reflectedTypeCache, declaringTypeHandle.GetRuntimeType(), bindingFlags)
        {
            m_tkField = tkField;
            m_name = null;
            m_fieldAttributes = fieldAttributes;
        }
        #endregion

        #region Internal Members
        internal override bool CacheEquals(object o)
        {
            MdFieldInfo m = o as MdFieldInfo;

            if ((object)m == null)
                return false;

            return m.m_tkField == m_tkField &&
                m_declaringType.GetTypeHandleInternal().GetModuleHandle().Equals(
                    m.m_declaringType.GetTypeHandleInternal().GetModuleHandle());
        }
        #endregion

        #region MemberInfo Overrides
        public override String Name
        {
            get
            {
                if (m_name == null)
                    m_name = GetRuntimeModule().MetadataImport.GetName(m_tkField).ToString();

                return m_name;
            }
        }

        public override int MetadataToken { get { return m_tkField; } }
        internal override RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); }
        #endregion

        #region FieldInfo Overrides
        public override RuntimeFieldHandle FieldHandle { get { throw new NotSupportedException(); } }
        public override FieldAttributes Attributes { get { return m_fieldAttributes; } }

        public override bool IsSecurityCritical { get { return DeclaringType.IsSecurityCritical; } }
        public override bool IsSecuritySafeCritical { get { return DeclaringType.IsSecuritySafeCritical; } }
        public override bool IsSecurityTransparent { get { return DeclaringType.IsSecurityTransparent; } }

        [DebuggerStepThroughAttribute]
        [Diagnostics.DebuggerHidden]
        public override Object GetValueDirect(TypedReference obj)
        {
            return GetValue(null);
        }

        [DebuggerStepThroughAttribute]
        [Diagnostics.DebuggerHidden]
        public override void SetValueDirect(TypedReference obj, Object value)
        {
            throw new FieldAccessException(SR.Acc_ReadOnly);
        }

        [DebuggerStepThroughAttribute]
        [Diagnostics.DebuggerHidden]
        public unsafe override Object GetValue(Object obj)
        {
            return GetValue(false);
        }

        public unsafe override Object GetRawConstantValue() { return GetValue(true); }

        private unsafe Object GetValue(bool raw)
        {
            // Cannot cache these because they could be user defined non-agile enumerations

            Object value = MdConstant.GetValue(GetRuntimeModule().MetadataImport, m_tkField, FieldType.GetTypeHandleInternal(), raw);

            if (value == DBNull.Value)
                throw new NotSupportedException(SR.Arg_EnumLitValueNotFound);

            return value;
        }

        [DebuggerStepThroughAttribute]
        [Diagnostics.DebuggerHidden]
        public override void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
        {
            throw new FieldAccessException(SR.Acc_ReadOnly);
        }

        public override Type FieldType
        {
            get
            {
                if (m_fieldType == null)
                {
                    ConstArray fieldMarshal = GetRuntimeModule().MetadataImport.GetSigOfFieldDef(m_tkField);

                    m_fieldType = new Signature(fieldMarshal.Signature.ToPointer(),
                        (int)fieldMarshal.Length, m_declaringType).FieldType;
                }

                return m_fieldType;
            }
        }

        public override Type[] GetRequiredCustomModifiers()
        {
            return Array.Empty<Type>();
        }

        public override Type[] GetOptionalCustomModifiers()
        {
            return Array.Empty<Type>();
        }

        #endregion
    }
}