/
CustomAttributeTypedArgument.cs
101 lines (75 loc) · 3.73 KB
/
CustomAttributeTypedArgument.cs
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
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;
namespace System.Reflection
{
public readonly partial struct CustomAttributeTypedArgument : IEquatable<CustomAttributeTypedArgument>
{
public static bool operator ==(CustomAttributeTypedArgument left, CustomAttributeTypedArgument right) => left.Equals(right);
public static bool operator !=(CustomAttributeTypedArgument left, CustomAttributeTypedArgument right) => !left.Equals(right);
private readonly object? _value;
private readonly Type _argumentType;
public CustomAttributeTypedArgument(Type argumentType, object? value)
{
ArgumentNullException.ThrowIfNull(argumentType);
_value = CanonicalizeValue(value);
_argumentType = argumentType;
}
public CustomAttributeTypedArgument(object value)
{
ArgumentNullException.ThrowIfNull(value);
_value = CanonicalizeValue(value);
_argumentType = value.GetType();
}
public override string ToString() => ToString(false);
internal string ToString(bool typed)
{
if (_argumentType is null)
return base.ToString()!;
if (ArgumentType.IsEnum)
return typed ? $"{Value}" : $"({ArgumentType.FullName}){Value}";
if (Value is null)
return typed ? "null" : $"({ArgumentType.Name})null";
if (ArgumentType == typeof(string))
return $"\"{Value}\"";
if (ArgumentType == typeof(char))
return $"'{Value}'";
if (ArgumentType == typeof(Type))
return $"typeof({((Type)Value!).FullName})";
if (ArgumentType.IsArray)
{
IList<CustomAttributeTypedArgument> array = (IList<CustomAttributeTypedArgument>)Value!;
Type elementType = ArgumentType.GetElementType()!;
var result = new ValueStringBuilder(stackalloc char[256]);
result.Append("new ");
result.Append(elementType.IsEnum ? elementType.FullName : elementType.Name);
result.Append('[');
int count = array.Count;
result.Append(count.ToString());
result.Append("] { ");
for (int i = 0; i < count; i++)
{
if (i != 0)
{
result.Append(", ");
}
result.Append(array[i].ToString(elementType != typeof(object)));
}
result.Append(" }");
return result.ToString();
}
return typed ? $"{Value}" : $"({ArgumentType.Name}){Value}";
}
public override int GetHashCode() => base.GetHashCode();
public override bool Equals([NotNullWhen(true)] object? obj) => obj is CustomAttributeTypedArgument cata && Equals(cata);
/// <summary>Indicates whether the current instance is equal to another instance of the same type.</summary>
/// <param name="other">An instance to compare with this instance.</param>
/// <returns>true if the current instance is equal to the other instance; otherwise, false.</returns>
public bool Equals(CustomAttributeTypedArgument other) => _value == other._value && _argumentType == other._argumentType;
public Type ArgumentType => _argumentType;
public object? Value => _value;
private static object? CanonicalizeValue(object? value) => (value is Enum e) ? e.GetValue() : value;
}
}