summaryrefslogtreecommitdiff
path: root/ThirdParty/CsvHelper-master/src/CsvHelper/ReflectionExtensions.cs
blob: e67c0b83b5e2fb5a81480a9c15cc115d0a446343 (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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Copyright 2009-2022 Josh Close
// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
// https://github.com/JoshClose/CsvHelper
using System;
using System.Reflection;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using System.Linq;

namespace CsvHelper
{
	/// <summary>
	/// Extensions to help with reflection.
	/// </summary>
	public static class ReflectionExtensions
	{
		/// <summary>
		/// Gets the type from the member.
		/// </summary>
		/// <param name="member">The member to get the type from.</param>
		/// <returns>The type.</returns>
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Type MemberType(this MemberInfo member)
		{
			var property = member as PropertyInfo;
			if (property != null)
			{
				return property.PropertyType;
			}

			var field = member as FieldInfo;
			if (field != null)
			{
				return field.FieldType;
			}

			throw new InvalidOperationException("Member is not a property or a field.");
		}

		/// <summary>
		/// Gets a member expression for the member.
		/// </summary>
		/// <param name="member">The member to get the expression for.</param>
		/// <param name="expression">The member expression.</param>
		/// <returns>The member expression.</returns>
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static MemberExpression GetMemberExpression(this MemberInfo member, Expression expression)
		{
			var property = member as PropertyInfo;
			if (property != null)
			{
				return Expression.Property(expression, property);
			}

			var field = member as FieldInfo;
			if (field != null)
			{
				return Expression.Field(expression, field);
			}

			throw new InvalidOperationException("Member is not a property or a field.");
		}

		/// <summary>
		/// Gets a value indicating if the given type is anonymous.
		/// True for anonymous, otherwise false.
		/// </summary>
		/// <param name="type">The type.</param>
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsAnonymous(this Type type)
		{
			if (type == null)
			{
				throw new ArgumentNullException(nameof(type));
			}

			// https://stackoverflow.com/a/2483054/68499
			var isAnonymous = Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false)
				&& type.IsGenericType
				&& type.Name.Contains("AnonymousType")
				&& (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$"))
				&& (type.Attributes & TypeAttributes.Public) != TypeAttributes.Public;

			return isAnonymous;
		}

		/// <summary>
		/// Gets a value indicating if the given type has a parameterless constructor.
		/// True if it has a parameterless constructor, otherwise false.
		/// </summary>
		/// <param name="type">The type.</param>
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool HasParameterlessConstructor(this Type type)
		{
			return type.GetConstructor(new Type[0]) != null;
		}

		/// <summary>
		/// Gets a value indicating if the given type has any constructors.
		/// </summary>
		/// <param name="type">The type.</param>
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool HasConstructor(this Type type)
		{
			return type.GetConstructors().Length > 0;
		}

		/// <summary>
		/// Gets the constructor that contains the most parameters.
		/// </summary>
		/// <param name="type">The type.</param>
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ConstructorInfo GetConstructorWithMostParameters(this Type type)
		{
			return type.GetConstructors()
				.OrderByDescending(c => c.GetParameters().Length)
				.First();
		}

		/// <summary>
		/// Gets a value indicating if the type is a user defined struct.
		/// True if it is a user defined struct, otherwise false.
		/// </summary>
		/// <param name="type">The type.</param>
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsUserDefinedStruct(this Type type)
		{
			return type.IsValueType && !type.IsPrimitive && !type.IsEnum;
		}

		/// <summary>
		/// Gets a string representation of the constructor.
		/// </summary>
		/// <param name="constructor">The constructor.</param>
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static string GetDefinition(this ConstructorInfo constructor)
		{
			var parameters = constructor.GetParameters();
			var definition = $"{constructor.Name}({string.Join(", ", parameters.Select(p => p.GetDefinition()))})";

			return definition;
		}

		/// <summary>
		/// Gets a string representation of the parameter.
		/// </summary>
		/// <param name="parameter">The parameter.</param>
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static string GetDefinition(this ParameterInfo parameter)
		{
			return $"{parameter.ParameterType.Name} {parameter.Name}";
		}
	}
}