类型 'T' 必须是引用类型才能将其用作泛型类型或方法 'TableClient.QueryAsync<T> 中的参数 'T'

The type 'T' must be a reference type in order to use it as parameter 'T' in the generic type or method 'TableClient.QueryAsync<T>

我正在使用 Azure.Data.Tables nuget 包的 12.0.0-beta.6。当我尝试调用 TableClient.GetQueryAsync 时,它给了我错误:

"类型'T'必须是引用类型才能在泛型类型或方法[=44=中用作参数'T' ]"

我看不出我做错了什么。有人可以就如何解决此错误提出建议吗?

  public async Task<IList<T>> QueryAsync<T>(string queryText, CancellationToken cancellationToken) where T : ITableStorageEntity
        {            
            TableClient tableClient = new TableServiceClient("MY_CONNECTION_STRING").GetTableClient("MY_TABLE_NAME");

            var queryResult = await tableClient.QueryAsync<T>(filter: queryText, cancellationToken: cancellationToken);
         
            // prepare and return result list
        }

如果我在声明中添加 class 约束,如下所示:

  public async Task<IList<T>> QueryAsync<T>(string queryText, CancellationToken cancellationToken) where T : ITableStorageEntity

那么这些是错误:

'T' 必须是具有 public 无参数构造函数的非抽象类型,以便在泛型类型或方法 'TableClient.QueryAsync(string, int?, IEnumerable, CancellationToken)'

类型 'T' 不能用作泛型类型或方法 'TableClient.QueryAsync(string, int?, IEnumerable, CancellationToken)' 中的类型参数 'T'。没有从 'T' 到 'Azure.Data.Tables.ITableEntity'.

的隐式引用转换

我们来看看the doc for that method:

public virtual Azure.AsyncPageable<T> QueryAsync<T> (string filter = default, int? maxPerPage = default, System.Collections.Generic.IEnumerable<string> select = default, System.Threading.CancellationToken cancellationToken = default) where T : class, Azure.Data.Tables.ITableEntity, new();

查看通用类型约束:

where T : class, Azure.Data.Tables.ITableEntity, new();

这意味着您传入的任何 T 必须是 class,必须实现 ITableEntity,并且必须具有无参数构造函数。

但是,您的方法并未强制执行此操作。您只需要 T 实现 ITableStorageEntity。您的方法理论上可以接受实现 ITableStorageEntity 但不是 class 或没有无参数构造函数的东西,并将其传递给 Azure 的 QueryAsync<T>,然后呢?你违反了规则!

您的方法需要具有与 QueryAsync<T> 相同的通用类型约束,或者更严格:

public async Task<IList<T>> QueryAsync<T>(string queryText, CancellationToken cancellationToken)
    where T : class, ITableStorageEntity, new()