Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting use of "dynamic" keyword as a type parameter at runtime

I suspect the short answer to this question is "no" but I'm interested in the ability to detect the use of the dynamic keyword at runtime in C# 4.0, specifically as a generic type parameter for a method.

To give some background, we have a RestClient class in a library shared among a number of our projects which takes a type parameter to specify a type that should be used when de-serializing the response, e.g.:

public IRestResponse<TResource> Get<TResource>(Uri uri, IDictionary<string, string> headers)
    where TResource : new()
{
    var request = this.GetRequest(uri, headers);
    return request.GetResponse<TResource>();
}

Unfortunately (due to reasons I won't get into here for the sake of brevity) using dynamic as the type parameter in order to return a dynamic type doesn't work properly - we've had to add a second signature to the class to return a dynamic response type:

public IRestResponse<dynamic> Get(Uri uri, IDictionary<string, string> headers)
{
    var request = this.GetRequest(uri, headers);
    return request.GetResponse();
}

However, using dynamic as the type parameter to the first method causes a very strange error that masks the actual problem and makes debugging the whole thing a headache. In order to help out the other programmers using the API, I'd like to try and detect the use of dynamic in the first method so that either it won't compile at all or when used an exception is thrown saying something along the lines of "use this other method if you want a dynamic response type".

Basically either:

public IRestResponse<TResource> Get<TResource>(Uri uri, IDictionary<string, string> headers)
    where TResource is not dynamic

or

public IRestResponse<TResource> Get<TResource>(Uri uri, IDictionary<string, string> headers)
    where TResource : new()
{
    if (typeof(TResource).isDynamic()) 
    {
           throw new Exception();
    }

    var request = this.GetRequest(uri, headers);

    return request.GetResponse<TResource>();
}

Are either of these things possible? We're using VS2010 and .Net 4.0 but I'd be interested in a .Net 4.5 solution for future reference if it's possible using newer language features.

like image 405
Henry Wilson Avatar asked Oct 04 '13 11:10

Henry Wilson


1 Answers

When someone does Get<dynamic>, at runtime TResource is object. As long as Get<object> isn't something your users would actually want to do, you can just check if TResource is object to catch both unexpected cases (object and dynamic).

public IRestResponse<TResource> Get<TResource>(Uri uri, IDictionary<string, string> headers)
    where TResource : new()
{
    if (typeof(TResource) == typeof(object)) 
    {
        throw new Exception("Use the dynamic one");
    }

    var request = this.GetRequest(uri, headers);

    return request.GetResponse<TResource>();
}
like image 79
Tim S. Avatar answered Sep 20 '22 13:09

Tim S.