Last active
March 18, 2025 11:39
-
-
Save koturn/dd47efb8bb334f15eb13f937dd1b0eee to your computer and use it in GitHub Desktop.
List<T>の内部の配列を取得するやつ(with Static Type Cache)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Reflection; | |
using System.Reflection.Emit; | |
namespace Koturn | |
{ | |
/// <summary> | |
/// Provides some utility methods of <see cref="List{T}"/>. | |
/// </summary> | |
public static class ListUtil | |
{ | |
/// <summary> | |
/// Get internal array of <see cref="List{T}"/>. | |
/// </summary> | |
public static T[] GetArray<T>(List<T> list) | |
{ | |
return ListUtil<T>.GetArray(list); | |
} | |
} | |
/// <summary> | |
/// Provides some utility methods of <see cref="List{T}"/>. | |
/// </summary> | |
public static class ListUtil<T> | |
{ | |
/// <summary> | |
/// Cache of delegate of <see cref="CreateGetArrayFunc"/>. | |
/// </summary> | |
private static Func<List<T>, T[]> _getArray; | |
/// <summary> | |
/// Get internal array of <see cref="List{T}"/>. | |
/// </summary> | |
/// <param name="list">Target list.</param> | |
/// <returns>Internal array of <see cref="List{T}"/>.</returns> | |
public static T[] GetArray(List<T> list) | |
{ | |
if (_getArray == null) | |
{ | |
_getArray = CreateGetArrayFunc(); | |
} | |
return _getArray(list); | |
} | |
/// <summary> | |
/// Create method which gets internal array of <see cref="List{T}"/>. | |
/// </summary> | |
/// <typeparam name="T">Element type of <see cref="List{T}"/>.</typeparam> | |
private static Func<List<T>, T[]> CreateGetArrayFunc() | |
{ | |
var dynMethod = new DynamicMethod( | |
"GetListArray", | |
typeof(T[]), | |
new [] { typeof(List<T>) }, | |
true); | |
var ilGen = dynMethod.GetILGenerator(); | |
ilGen.Emit(OpCodes.Ldarg_0); | |
ilGen.Emit( | |
OpCodes.Ldfld, | |
typeof(List<T>).GetField( | |
"_items", | |
BindingFlags.GetField | |
| BindingFlags.NonPublic | |
| BindingFlags.Instance)); | |
ilGen.Emit(OpCodes.Ret); | |
return (Func<List<T>, T[]>)dynMethod.CreateDelegate(typeof(Func<List<T>, T[]>)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment