Example #1
0
        public void Reflect()
        {
            // Cannot happen from the constructor, but will occur
            // if the type doesn't exist and fails to be deserialized
            if (targetType == null)
            {
                if (targetTypeName != null)
                {
                    throw new MissingMemberException(targetTypeName, name);
                }
                else
                {
                    throw new MissingMemberException("Target type not found.");
                }
            }

            _source = Source.Unknown;

            _fieldInfo       = null;
            _propertyInfo    = null;
            _methodInfo      = null;
            _constructorInfo = null;

            fieldAccessor    = null;
            propertyAccessor = null;
            methodInvoker    = null;

            MemberInfo[] candidates;
            try
            {
                candidates = targetType.GetExtendedMember(name, SupportedMemberTypes, SupportedBindingFlags);
            }
            catch (NotSupportedException e)
            {
                throw new InvalidOperationException($"An error occured when trying to reflect the member '{name}' of the type '{targetType.FullName}' in a '{GetType().Name}' unit. Supported member types: {SupportedMemberTypes}, supported binding flags: {SupportedBindingFlags}", e);
            }

            if (candidates.Length == 0) // Not found, check if it might have been renamed
            {
                var renamedMembers = RuntimeCodebase.RenamedMembers(targetType);

                string newName;

                if (renamedMembers.TryGetValue(name, out newName))
                {
                    name = newName;

                    try
                    {
                        candidates = targetType.GetExtendedMember(name, SupportedMemberTypes, SupportedBindingFlags);
                    }
                    catch (NotSupportedException e)
                    {
                        throw new InvalidOperationException($"An error occured when trying to reflect the renamed member '{name}' of the type '{targetType.FullName}' in a '{GetType().Name}' unit. Supported member types: {SupportedMemberTypes}, supported binding flags: {SupportedBindingFlags}", e);
                    }
                }
            }

            if (candidates.Length == 0) // Nope, not even, abort
            {
                throw new MissingMemberException($"No matching member found: '{targetType.Name}.{name}'");
            }

            MemberTypes?memberType = null;

            foreach (var candidate in candidates)
            {
                if (memberType == null)
                {
                    memberType = candidate.MemberType;
                }
                else if (candidate.MemberType != memberType && !candidate.IsExtensionMethod())
                {
                    // This theoretically shouldn't happen according to the .NET specification, I believe
                    Debug.LogWarning($"Multiple members with the same name are of a different type: '{targetType.Name}.{name}'");
                    break;
                }
            }

            switch (memberType)
            {
            case MemberTypes.Field:
                ReflectField(candidates);
                break;

            case MemberTypes.Property:
                ReflectProperty(candidates);
                break;

            case MemberTypes.Method:
                ReflectMethod(candidates);
                break;

            case MemberTypes.Constructor:
                ReflectConstructor(candidates);
                break;

            default:
                throw new UnexpectedEnumValueException <MemberTypes>(memberType.Value);
            }

            isReflected = true;
        }