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

本文关键字:关键字 类型参数 dynamic 运行时 检测 | 更新日期: 2023-09-27 18:33:50

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

为了提供一些背景知识,我们在多个项目之间共享的库中有一个 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>();
}

不幸的是(由于简洁起见,我不会在这里讨论(使用 dynamic 作为类型参数以返回动态类型无法正常工作 - 我们不得不向类添加第二个签名以返回动态响应类型:

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

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

基本上是:

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

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>();
}

这些事情都可能吗?我们使用的是VS2010和.Net 4.0,但如果可以使用较新的语言功能,我会对.Net 4.5解决方案感兴趣,以供将来参考。

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

当有人Get<dynamic>时,运行时TResource object。只要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>();
}