Is it possible to make the transition from F (Type) to F <T> without reflection and without a dictionary?

First, a small introduction.

I have functions:

static class C
{
  static void F1(Type type)
  {
    // Do something to invoke F2<T>
  }
  static void F2<T>()
  {
    // bla bla bla
  }
}

I want to call F1(Type), which, in turn, should go to the general context related to this type parameter and call the common instance F2<T>.

A naive implementation would be a simple reflection, for example (I omit the anchor flags for clarity):

void F1(Type type)
{
  var f2MethodInfo = typeof(C).GetMethod("F2").MakeGenericMethod(type);
  f2MethodInfo.Invoke(null, new object[0]);
}

A more advanced implementation will keep the open method information for F2 typeof(C).GetMethod("F2")aside, but still it's basically the same.

If it F1is called many times, and we want to improve performance, then the standard solution "on the market" uses a dictionary and a method Delegate.CreateDelegate, for example:

IDictionary<Type, Action> m_cache = new Dictionary<Type, Action>();
MethodInfo F2MethodInfo = typeof(C).GetMethod("F2");
void F1(Type type)
{
  Action action;
  if (!m_cache.TryGetValue(type, out action))
  {
    m_cache[type] = action = (Action)Delegate.CreateDelegate(typeof(Action), F2MethodInfo.MakeGenericMethod(type));
  }
  action();
}

And now to my question. Is it possible to completely exclude a dictionary?

, Reflection.Emit, Type F2MethodInfo ? . , .

.

, fancy emitted , F2, . ?

+3
5

F (Type) F ?

, MakeGenericType - .

, ; - call, MethodInfo , Delegate.CreateDelegate.

, , Reflection.Emit CodeDom . , , , ?

+1

, , , . Invoke, IL ( LGC, Reflection.Emit ), .

, LCG .

0

, F () , factory, Action.

, .

readonly IDictionary<Type, Action> _BlablasByType = new Dictionary<Type, Action>();
readonly MethodInfo _F2MethodInfo = typeof(C).GetMethod("F2");
void GetBlablaFor(Type type)
{
  Action action;
  if (! _BlablasByType.TryGetValue(type, out action))
  {
    _BlablasByType.Add(type, 
                       action = (Action)Delegate.CreateDelegate(typeof(Action),                                                                                                                                        
                                                                _F2MethodInfo.MakeGenericMethod(type));
  }
  return action;
}

var blabla = GetBlablaFor(typeof(Abc));
for(int i = 0; i < 10000; i++)
  blabla();
0

:

static void F1(Type type) {
    // do stuff
}

static void F2<T>() {
    F1(typeof(T))
}

, , , .

Java- :

static <T> void F1(Class<T> clazz) {
    // do stuff
}

, .

0

. /, .

0

Source: https://habr.com/ru/post/1725252/


All Articles