예제 #1
0
파일: ClrObject.cs 프로젝트: tiandian/msos
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (IsNull())
            {
                result = new ClrNullValue(m_heap);
                return(true);
            }

            if (binder.Name == "__Size")
            {
                result = m_type.GetSize(m_addr);
                return(true);
            }

            if (binder.Name == "__Type")
            {
                result = m_type.Name;
                return(true);
            }

            if (binder.Name == "__Address")
            {
                result = String.Format("{0:x16}", m_addr);
                return(true);
            }

            if (binder.Name == "__Fields")
            {
                result = (from f in m_type.Fields where f.Type != null select new { Name = f.Name, Type = f.Type.Name }).ToArray();
                return(true);
            }

            ClrInstanceField field = null;

            foreach (var instanceField in m_type.Fields)
            {
                // Auto-generated properties have this ugly <> thing around their fields that you can't put
                // in a C# expression. Clean them up to make them accessible by their property name.
                var cleanFieldName = instanceField.Name;
                if (cleanFieldName.StartsWith("<") && cleanFieldName.EndsWith(">k__BackingField"))
                {
                    cleanFieldName = cleanFieldName.Substring(
                        1, cleanFieldName.Length - (1 + ">k__BackingField".Length));
                }
                if (cleanFieldName == binder.Name)
                {
                    field = instanceField;
                    break;
                }
            }

            if (field == null)
            {
                if (ClrDynamicClass.GetStaticField(m_heap, m_type, binder, out result))
                {
                    return(true);
                }

                throw new InvalidOperationException(string.Format("Type '{0}' does not contain a '{1}' field.", m_type.Name, binder.Name));
            }

            if (field.IsOfPrimitiveType())
            {
                object value = field.GetValue(m_addr, m_inner);
                if (value == null)
                {
                    result = new ClrNullValue(m_heap);
                }
                else
                {
                    result = new ClrPrimitiveValue(value, field.ElementType);
                }

                return(true);
            }
            else if (field.IsOfValueClass())
            {
                ulong addr = field.GetAddress(m_addr, m_inner);
                result = new ClrObject(m_heap, field.Type, addr, true);
                return(true);
            }
            else if (field.ElementType == ClrElementType.String)
            {
                ulong addr = field.GetAddress(m_addr, m_inner);
                if (!m_heap.Runtime.ReadPointer(addr, out addr))
                {
                    result = new ClrNullValue(m_heap);
                    return(true);
                }

                result = new ClrObject(m_heap, field.Type, addr);
                return(true);
            }
            else
            {
                object value = field.GetValue(m_addr, m_inner);
                if (value == null)
                {
                    result = new ClrNullValue(m_heap);
                }
                else
                {
                    result = new ClrObject(m_heap, field.Type, (ulong)value);
                }

                return(true);
            }
        }