Skip to content
This repository was archived by the owner on May 9, 2023. It is now read-only.

Commit ac9c2d5

Browse files
committed
Use recursive GetGenericArguments to catch unusual type structures, cleanup InteractiveList value caching
1 parent 496a5de commit ac9c2d5

File tree

3 files changed

+32
-15
lines changed

3 files changed

+32
-15
lines changed

src/Core/Reflection/Extensions.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,27 @@ public static HashSet<Type> GetImplementationsOf(this Type baseType, bool allowA
3636

3737
// ------- Misc extensions --------
3838

39+
/// <summary>
40+
/// Recursively check the type and its base types to find any generic arguments.
41+
/// </summary>
42+
public static bool TryGetGenericArguments(this Type type, out Type[] args)
43+
{
44+
if (type.IsGenericType)
45+
{
46+
args = type.GetGenericArguments();
47+
return true;
48+
}
49+
else if (type.BaseType != null)
50+
{
51+
return TryGetGenericArguments(type.BaseType, out args);
52+
}
53+
else
54+
{
55+
args = null;
56+
return false;
57+
}
58+
}
59+
3960
/// <summary>
4061
/// Safely try to get all Types inside an Assembly.
4162
/// </summary>

src/UI/IValues/InteractiveDictionary.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,11 @@ public override void SetValue(object value)
7575
else
7676
{
7777
var type = value.GetActualType();
78-
if (type.IsGenericType && type.GetGenericArguments().Length == 2)
79-
{
80-
KeyType = type.GetGenericArguments()[0];
81-
ValueType = type.GetGenericArguments()[1];
78+
79+
if (type.TryGetGenericArguments(out var args) && args.Length == 2)
80+
{
81+
KeyType = args[0];
82+
ValueType = args[1];
8283
}
8384
else
8485
{

src/UI/IValues/InteractiveList.cs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ public class InteractiveList : InteractiveValue, ICellPoolDataSource<CacheListEn
2828
private bool IsWritableGenericIList;
2929
private PropertyInfo genericIndexer;
3030

31-
public int ItemCount => values.Count;
32-
private readonly List<object> values = new List<object>();
31+
public int ItemCount => cachedEntries.Count;
3332
private readonly List<CacheListEntry> cachedEntries = new List<CacheListEntry>();
3433

3534
public ScrollPool<CacheListEntryCell> ListScrollPool { get; private set; }
@@ -53,7 +52,6 @@ public override void ReleaseFromOwner()
5352
private void ClearAndRelease()
5453
{
5554
RefIList = null;
56-
values.Clear();
5755

5856
foreach (var entry in cachedEntries)
5957
{
@@ -70,14 +68,14 @@ public override void SetValue(object value)
7068
if (value == null)
7169
{
7270
// should never be null
73-
if (values.Any())
71+
if (cachedEntries.Any())
7472
ClearAndRelease();
7573
}
7674
else
7775
{
7876
var type = value.GetActualType();
79-
if (type.IsGenericType)
80-
EntryType = type.GetGenericArguments()[0];
77+
if (type.TryGetGenericArguments(out var args))
78+
EntryType = args[0];
8179
else if (type.HasElementType)
8280
EntryType = type.GetElementType();
8381
else
@@ -102,7 +100,6 @@ private void CacheEntries(object value)
102100
else
103101
IsWritableGenericIList = false;
104102

105-
values.Clear();
106103
int idx = 0;
107104

108105
if (ReflectionUtility.TryGetEnumerator(value, out IEnumerator enumerator))
@@ -113,8 +110,6 @@ private void CacheEntries(object value)
113110
{
114111
var entry = enumerator.Current;
115112

116-
values.Add(entry);
117-
118113
// If list count increased, create new cache entries
119114
CacheListEntry cache;
120115
if (idx >= cachedEntries.Count)
@@ -132,9 +127,9 @@ private void CacheEntries(object value)
132127
}
133128

134129
// Remove excess cached entries if list count decreased
135-
if (cachedEntries.Count > values.Count)
130+
if (cachedEntries.Count > idx)
136131
{
137-
for (int i = cachedEntries.Count - 1; i >= values.Count; i--)
132+
for (int i = cachedEntries.Count - 1; i >= idx; i--)
138133
{
139134
var cache = cachedEntries[i];
140135
if (cache.CellView != null)

0 commit comments

Comments
 (0)