문제

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.

도움이 되었습니까?

해결책

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>();
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top