If you need to access internal array repeatedly, it good practice to store accessor as delegate.
In this example, it's delegate to dynamic method. First call may not be fast, but subsequent calls (on List of same type) will be much faster.
public static class ListExtensions
{
static class ArrayAccessor<T>
{
public static Func<List<T>, T[]> Getter;
static ArrayAccessor()
{
var dm = new DynamicMethod("get", MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, typeof(T[]), new Type[] { typeof(List<T>) }, typeof(ArrayAccessor<T>), true);
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0); // Load List<T> argument
il.Emit(OpCodes.Ldfld, typeof(List<T>).GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance)); // Replace argument by field
il.Emit(OpCodes.Ret); // Return field
Getter = (Func<List<T>, T[]>)dm.CreateDelegate(typeof(Func<List<T>, T[]>));
}
}
public static T[] GetInternalArray<T>(this List<T> list)
{
return ArrayAccessor<T>.Getter(list);
}
}
Make sure to include:
using System.Reflection;
using System.Reflection.Emit;
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…