Skip to content

[Jit] Proposal: Non-shared generics #9682

@benaadams

Description

@benaadams

Proposal

[MethodImpl(MethodImplOptions.NonSharedGeneric)] 

If you had for example aspnet/KestrelHttpServer#2290

TFeature IFeatureCollection.Get<TFeature>()
{
    TFeature feature;
    if (typeof(TFeature) == typeof(IHttpRequestFeature))
    {
        feature = (TFeature)_currentIHttpRequestFeature;
    }
    else if (typeof(TFeature) == typeof(IHttpResponseFeature))
    {
        feature = (TFeature)_currentIHttpResponseFeature;
    }
    else if (typeof(TFeature) == typeof(IHttpRequestIdentifierFeature))
    {
        feature = (TFeature)_currentIHttpRequestIdentifierFeature;
    }
    else if (typeof(TFeature) == typeof(IServiceProvidersFeature))
    {
        feature = (TFeature)_currentIServiceProvidersFeature;
    }
    else if (typeof(TFeature) == typeof(IHttpRequestLifetimeFeature))
    {
        feature = (TFeature)_currentIHttpRequestLifetimeFeature;
    }
    else if (typeof(TFeature) == typeof(IHttpConnectionFeature))
    {
        feature = (TFeature)_currentIHttpConnectionFeature;
    }
    else if (typeof(TFeature) == typeof(IHttpAuthenticationFeature))
    {
        feature = (TFeature)_currentIHttpAuthenticationFeature;
    }
    else if (typeof(TFeature) == typeof(IQueryFeature))
    {
        feature = (TFeature)_currentIQueryFeature;
    }
    else if (typeof(TFeature) == typeof(IFormFeature))
    {
        feature = (TFeature)_currentIFormFeature;
    }
    else if (typeof(TFeature) == typeof(IHttpUpgradeFeature))
    {
        feature = (TFeature)_currentIHttpUpgradeFeature;
    }
    else if (typeof(TFeature) == typeof(IHttp2StreamIdFeature))
    {
        feature = (TFeature)_currentIHttp2StreamIdFeature;
    }
    else if (typeof(TFeature) == typeof(IResponseCookiesFeature))
    {
        feature = (TFeature)_currentIResponseCookiesFeature;
    }
    else if (typeof(TFeature) == typeof(IItemsFeature))
    {
        feature = (TFeature)_currentIItemsFeature;
    }
    else if (typeof(TFeature) == typeof(ITlsConnectionFeature))
    {
        feature = (TFeature)_currentITlsConnectionFeature;
    }
    else if (typeof(TFeature) == typeof(IHttpWebSocketFeature))
    {
        feature = (TFeature)_currentIHttpWebSocketFeature;
    }
    else if (typeof(TFeature) == typeof(ISessionFeature))
    {
        feature = (TFeature)_currentISessionFeature;
    }
    else if (typeof(TFeature) == typeof(IHttpMaxRequestBodySizeFeature))
    {
        feature = (TFeature)_currentIHttpMaxRequestBodySizeFeature;
    }
    else if (typeof(TFeature) == typeof(IHttpMinRequestBodyDataRateFeature))
    {
        feature = (TFeature)_currentIHttpMinRequestBodyDataRateFeature;
    }
    else if (typeof(TFeature) == typeof(IHttpMinResponseDataRateFeature))
    {
        feature = (TFeature)_currentIHttpMinResponseDataRateFeature;
    }
    else if (typeof(TFeature) == typeof(IHttpBodyControlFeature))
    {
        feature = (TFeature)_currentIHttpBodyControlFeature;
    }
    else if (typeof(TFeature) == typeof(IHttpSendFileFeature))
    {
        feature = (TFeature)_currentIHttpSendFileFeature;
    }
    else
    {
        feature = (TFeature)(ExtraFeatureGet(typeof(TFeature)));
    }

    if (feature != null)
    {
        return feature;
    }

    return (TFeature)ConnectionFeatures[typeof(TFeature)];
}

and you marked it with this MethodImplOptions.NonSharedGeneric it would elide all the type checks for classes/interfaces as it does for structs meaning it would turn into a branchless function (and create an implementation for every TFeature type it was called with).

Still performance issues with it being an interface generic method IFeatureCollection.Get<TFeature>(); but better performance...

public interface IFeatureCollection : IEnumerable<KeyValuePair<Type, object>>
{
    bool IsReadOnly { get; }
    int Revision { get; }
    object this[Type key] { get; set; }
    TFeature Get<TFeature>();
    void Set<TFeature>(TFeature instance);
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions