public static CallSite Create(Type delegateType, CallSiteBinder binder)
{
ContractUtils.RequiresNotNull(delegateType, nameof(delegateType));
ContractUtils.RequiresNotNull(binder, nameof(binder));
if (!delegateType.IsSubclassOf(typeof(MulticastDelegate))) throw System.Linq.Expressions.Error.TypeMustBeDerivedFromSystemDelegate();
CacheDict<Type, Func<CallSiteBinder, CallSite>> ctors = s_siteCtors;
if (ctors == null) {
// It's okay to just set this, worst case we're just throwing away some data
s_siteCtors = ctors = new CacheDict<Type, Func<CallSiteBinder, CallSite>>(100);
}
Func<CallSiteBinder, CallSite> ctor;
MethodInfo method = null;
if (!ctors.TryGetValue(delegateType, out ctor))
{
method = typeof(CallSite<>).MakeGenericType(delegateType).GetMethod(nameof(Create));
if (delegateType.CanCache())
{
ctor = (Func<CallSiteBinder, CallSite>)method.CreateDelegate(typeof(Func<CallSiteBinder, CallSite>));
ctors.Add(delegateType, ctor);
}
}
if (ctor != null)
{
return ctor(binder);
}
// slow path
return (CallSite)method.Invoke(null, new object[] { binder });
}
}