【问题标题】: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> [duplicate]类型“T”必须是引用类型才能将其用作泛型类型或方法“TableClient.QueryAsync<T>”中的参数“T”[重复]
【发布时间】:2021-03-17 15:07:09
【问题描述】:

我正在使用 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
        }

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

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

那么这些是错误:

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

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

【问题讨论】:

  • 如果在接口之外添加class作为约束,应该可以解决问题。
  • 不幸的是,它没有。我将编辑问题以包括当我这样做时会发生什么。
  • 你的方法好像是在实现了接口的类上定义的,你也需要更新接口对应的方法吗?
  • 确实如此,谢谢。我已将类约束添加到接口的方法定义中。我将产生的错误添加到问题中。
  • 我认为您缺少约束 where T : class, Azure.Data.Tables.ITableEntity, new()Azure.Data.Tables.ITableEntity 位,但如果没有看到您的最新代码,很难判断

标签: c# generics azure-table-storage


【解决方案1】:

我们来看看the doc for that method

公共虚拟 Azure.AsyncPageable QueryAsync(字符串过滤器 = 默认值,int?maxPerPage = 默认值,System.Collections.Generic.IEnumerable 选择 = 默认值,System.Threading.CancellationToken 取消令牌 = 默认值)其中 T:类,Azure.Data。 Tables.ITableEntity, new();

查看泛型类型约束:

其中 T : 类,Azure.Data.Tables.ITableEntity,new();

这意味着你传入的任何T都必须是一个类,必须实现ITableEntity,并且必须有一个无参数的构造函数。

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

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

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

【讨论】:

  • 谢谢,这很有帮助!阅读文档总是很好:-) 我想我现在的接口声明是正确的。我仍然有一个错误,我在 cmets 中对你之前的答案进行了描述。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多