Welcome to mirror list, hosted at ThFree Co, Russian Federation.

CustomAttributeTypedArgument.cs « Reflection « System « src « System.Private.CoreLib « src - github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 8f09f8236464f4c8dcdeb6827b0dc26a03b73fde (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
// 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.Globalization;
using System.Collections.Generic;

namespace System.Reflection
{
    public struct CustomAttributeTypedArgument
    {
        public CustomAttributeTypedArgument(object value)
        {
            // value cannot be null.
            if (value == null)
                throw new ArgumentNullException(nameof(value));

            Value = CanonicalizeValue(value);
            ArgumentType = value.GetType();
        }

        public CustomAttributeTypedArgument(Type argumentType, object value)
        {
            // value can be null.
            if (argumentType == null)
                throw new ArgumentNullException(nameof(argumentType));

            Value = (value == null) ? null : CanonicalizeValue(value);
            ArgumentType = argumentType;
#if MONO
            if (value is Array a) {
                Type etype = a.GetType().GetElementType();
                CustomAttributeTypedArgument[] new_value = new CustomAttributeTypedArgument[a.GetLength(0)];
                for (int i = 0; i < new_value.Length; ++i) {
                    var val = a.GetValue (i);
                    var elemType = etype == typeof (System.Object) ? val.GetType () : etype;
                    new_value[i] = new CustomAttributeTypedArgument (elemType, val);
                }
                Value = new System.Collections.ObjectModel.ReadOnlyCollection <CustomAttributeTypedArgument>(new_value);
            }
#endif
        }

        public Type ArgumentType { get; }
        public object Value { get; }

        public override bool Equals(object obj) => obj == (object)this;
        public override int GetHashCode() => base.GetHashCode();
        public static bool operator ==(CustomAttributeTypedArgument left, CustomAttributeTypedArgument right) => left.Equals(right);
        public static bool operator !=(CustomAttributeTypedArgument left, CustomAttributeTypedArgument right) => !(left.Equals(right));

        public override string ToString() => ToString(typed: false);

        internal string ToString(bool typed)
        {
            if (ArgumentType == null)
                return base.ToString(); // Someone called ToString() on "default(CustomAttributeTypedArgument)"

            try
            {
                if (ArgumentType.IsEnum)
                    return string.Format(CultureInfo.CurrentCulture, typed ? "{0}" : "({1}){0}", Value, ArgumentType.FullNameOrDefault);

                else if (Value == null)
                    return string.Format(CultureInfo.CurrentCulture, typed ? "null" : "({0})null", ArgumentType.NameOrDefault);

                else if (ArgumentType == typeof(string))
                    return string.Format(CultureInfo.CurrentCulture, "\"{0}\"", Value);

                else if (ArgumentType == typeof(char))
                    return string.Format(CultureInfo.CurrentCulture, "'{0}'", Value);

                else if (ArgumentType == typeof(Type))
                    return string.Format(CultureInfo.CurrentCulture, "typeof({0})", ((Type)Value).FullNameOrDefault);

                else if (ArgumentType.IsArray)
                {
                    string result = null;
                    IList<CustomAttributeTypedArgument> array = Value as IList<CustomAttributeTypedArgument>;

                    Type elementType = ArgumentType.GetElementType();
                    result = string.Format(CultureInfo.CurrentCulture, @"new {0}[{1}] {{ ", elementType.IsEnum ? elementType.FullNameOrDefault : elementType.NameOrDefault, array.Count);

                    for (int i = 0; i < array.Count; i++)
                        result += string.Format(CultureInfo.CurrentCulture, i == 0 ? "{0}" : ", {0}", array[i].ToString(elementType != typeof(object)));

                    return result += " }";
                }

                return string.Format(CultureInfo.CurrentCulture, typed ? "{0}" : "({1}){0}", Value, ArgumentType.NameOrDefault);
            }
            catch (MissingMetadataException)
            {
                return base.ToString(); // Failsafe. Code inside "try" should still strive to avoid trigging a MissingMetadataException as caught exceptions are annoying when debugging.
            }
        }

        private static object CanonicalizeValue(object value)
        {
            if (value.GetType().IsEnum)
                return ((Enum)value).GetValue();
            return value;
        }
    }
}