检测在运行时使用"dynamic"关键字作为类型参数

Hen*_*son 7 .net c# dynamic .net-4.0 generic-type-argument

我怀疑这个问题的简短回答是"不",但我对在C#4.0中运行时检测动态关键字的使用感兴趣,特别是作为方法的泛型类型参数.

为了给出一些背景知识,我们在一些库中共享了一个RestClient类,这些类在我们的许多项目中共享,它们使用一个类型参数来指定在反序列化响应时应该使用的类型,例如:

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

不幸的是(由于我不会为了简洁而进入这里的原因)使用dynamic作为类型参数以返回动态类型不能正常工作 - 我们必须在类中添加第二个签名返回动态响应类型:

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

但是,使用dynamic作为第一个方法的类型参数会导致一个非常奇怪的错误,它会掩盖实际问题并使调试整个过程变得令人头疼.为了帮助其他使用API​​的程序员,我想尝试在第一种方法中检测动态的使用,以便它根本不会编译或者在使用时会抛出异常.如果你想要一个动态响应类型,请"使用其他方法".

基本上:

public IRestResponse<TResource> Get<TResource>(Uri uri, IDictionary<string, string> headers)
    where TResource is not dynamic
Run Code Online (Sandbox Code Playgroud)

要么

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>();
}
Run Code Online (Sandbox Code Playgroud)

这两件事都有可能吗?我们正在使用VS2010和.Net 4.0,但如果可以使用更新的语言功能,我会对.Net 4.5解决方案感兴趣,以备将来参考.

Tim*_* S. 3

当有人这样做时Get<dynamic>,在运行时TResourceobject。只要Get<object>不是您的用户真正想要做的事情,您就可以检查是否TResource捕获object意外情况 (objectdynamic)。

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>();
}
Run Code Online (Sandbox Code Playgroud)