Select then ToList() doesn't work ?
LoisBoombyte opened this issue · 2 comments
LoisBoombyte commented
Hi, I executed this simple test in Unity and the ToList() doesn't work well... ?!
public List<InboxItem> _firstList = null;
public class InboxItem
{
public int int1;
public float float1;
public int int2;
}
//I just initialize the list with 10.000 items
private void Start()
{
_firstList = new List<InboxItem>(100000);
for (int i = 0; i < 100000; i++)
{
_firstList.Add(new InboxItem()
{
int1 = i,
float1 = i,
int2 = 2 * i
});
}
}
private void TestSelectThenToListHyperLinq()
{
Debug.Log("TestSelectThenToListHyperLinq");
var select = _firstList.AsValueEnumerable().Select(x => x.int1);
var list = select.ToList();
var array = select.ToArray();
Debug.Log("list count = " + list.Count); //return 0 !!!!
Debug.Log("array Length = " + array.Length); //return n
}
private void TestSelectThenToListLinq()
{
Debug.Log("TestSelectThenToListLinq");
var select = _firstList.Select(x => x.int1);
var list = select.ToList();
var array = select.ToArray();
Debug.Log("list count = " + list.Count); //return n
Debug.Log("array Length = " + array.Length); //return n
}
LoisBoombyte commented
if I use Linq's ToList() after your Select() it also work correctly. Problems seems to be when I use your own ToList()
R-033 commented
Had the same issue. This is caused by unsafe cast from List to ListLayout not working the same way in .Net Framework/Mono. The problem was in ListExtensions class. I did quite a bit of testing and ended up rewriting the problematic bit completely. I don't know if this is the best solution but it worked for me.
static List<TSource> WrapArray(TSource[] source)
{
var result = new List<TSource>();
ref var layout = ref ILExtensions.AsRef<ListLayout<TSource>>(ILExtensions.AddressOf(result));
layout.Items = source;
layout.Count = source.Length;
return result;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MonoObject
{
public IntPtr MonoVTable;
public IntPtr Monitor;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ListLayout<T>
{
public MonoObject Mono;
public T[] Items;
public int Count;
public int Version;
}
Easier solution is to just use older version of this repo (around beginning of 2020) before they dropped .Net Framework support.