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

Tim*_*imH 3 c# generics azure-table-storage

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

“类型‘T’必须是引用类型,才能将其用作泛型类型或方法‘TableClient.GetEntityAsync(string, string, IEnumerable, CancellationToken)’中的参数‘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
        }
Run Code Online (Sandbox Code Playgroud)

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

  public async Task<IList<T>> QueryAsync<T>(string queryText, CancellationToken cancellationToken) where T : ITableStorageEntity
Run Code Online (Sandbox Code Playgroud)

那么这些是错误:

“T”必须是具有公共无参数构造函数的非抽象类型,才能将其用作泛型类型或方法“TableClient.QueryAsync(string, int?, IEnumerable, CancellationToken)”中的参数“T”

类型“T”不能用作泛型类型或方法“TableClient.QueryAsync(string, int?, IEnumerable, CancellationToken)”中的类型参数“T”。不存在从“T”到“Azure.Data.Tables.ITableEntity”的隐式引用转换。

can*_*on7 10

让我们看看该方法的文档

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您传入的任何内容都必须是类,必须实现ITableEntity,并且必须具有无参数构造函数。

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

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

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