Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- static class Dynamic
- {
- public static class GetEnumerator<TEnumerable, TEnumerator, TSource>
- where TEnumerable : IEnumerable<TSource>
- where TEnumerator : IEnumerator<TSource>
- {
- public static Func<TEnumerable, TEnumerator> Invoke { get; } = Create();
- static Func<TEnumerable, TEnumerator> Create()
- {
- var enumerableType = typeof(TEnumerable);
- var getEnumerator = enumerableType.GetEnumeratorMethod<TSource>();
- if (getEnumerator is null || !typeof(TEnumerator).IsAssignableFrom(getEnumerator.ReturnType))
- throw new Exception($"'{enumerableType.FullName}': type must be implicitly convertible to '{typeof(TEnumerable).FullName}'");
- var enumerable = Expression.Parameter(enumerableType, "enumerable");
- var body = Expression.Call(enumerable, getEnumerator);
- return Expression.Lambda<Func<TEnumerable, TEnumerator>>(body, enumerable).Compile();
- }
- }
- static MethodInfo GetEnumeratorMethod<TSource>(this Type enumerableType)
- {
- const string MethodName = "GetEnumerator";
- var method = enumerableType.GetMethod(MethodName, BindingFlags.Public | BindingFlags.Instance);
- if (!(method is null))
- return method;
- var type = typeof(IEnumerable<>).MakeGenericType(typeof(TSource));
- if (type.IsAssignableFrom(enumerableType))
- return type.GetMethod(MethodName);
- type = typeof(IEnumerable);
- if (type.IsAssignableFrom(enumerableType))
- return type.GetMethod(MethodName);
- return null;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement