-
Notifications
You must be signed in to change notification settings - Fork 976
Expand file tree
/
Copy pathReflectionPath.cs
More file actions
108 lines (94 loc) · 3.35 KB
/
Copy pathReflectionPath.cs
File metadata and controls
108 lines (94 loc) · 3.35 KB
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
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ReflectionPath.cs" company="OxyPlot">
// Copyright (c) 2014 OxyPlot contributors
// </copyright>
// <summary>
// Provides functionality to reflect a path of properties.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
#nullable enable
namespace OxyPlot
{
using System;
using System.Reflection;
/// <summary>
/// Provides functionality to reflect a path of properties.
/// </summary>
public class ReflectionPath
{
/// <summary>
/// The path items.
/// </summary>
private readonly string[] items;
/// <summary>
/// The property metadata.
/// </summary>
private readonly PropertyInfo?[] infos;
/// <summary>
/// The reflected types.
/// </summary>
private readonly Type?[] reflectedTypes;
/// <summary>
/// Initializes a new instance of the <see cref="ReflectionPath"/> class.
/// </summary>
/// <param name="path">The reflection path.</param>
public ReflectionPath(string path)
{
this.items = path != null ? path.Split('.') : new string[0];
this.infos = new PropertyInfo[this.items.Length];
this.reflectedTypes = new Type[this.items.Length];
}
/// <summary>
/// Gets the value for the specified instance.
/// </summary>
/// <param name="instance">The instance.</param>
/// <returns>
/// The value.
/// </returns>
/// <exception cref="System.InvalidOperationException">Could not find property.</exception>
public object? GetValue(object instance)
{
object? result;
if (this.TryGetValue(instance, out result))
{
return result;
}
throw new InvalidOperationException("Could not find property " + string.Join(".", this.items) + " in " + instance);
}
/// <summary>
/// Tries to get the value for the specified instance.
/// </summary>
/// <param name="instance">The instance.</param>
/// <param name="result">The result.</param>
/// <returns>
/// <c>true</c> if the value was found.
/// </returns>
public bool TryGetValue(object instance, out object? result)
{
var current = instance;
for (int i = 0; i < this.items.Length; i++)
{
if (current == null)
{
result = null;
return true;
}
var currentType = current.GetType();
var pi = this.infos[i];
if (pi == null || this.reflectedTypes[i] != currentType)
{
pi = this.infos[i] = currentType.GetRuntimeProperty(this.items[i]);
this.reflectedTypes[i] = currentType;
}
if (pi == null)
{
result = null;
return false;
}
current = pi.GetValue(current, null);
}
result = current;
return true;
}
}
}