【问题标题】:Compile error using Azure Storage Client library 3.0 method executequery<T> where T is tableentity使用 Azure 存储客户端库 3.0 方法 executequery<T> 编译错误,其中 T 是表实体
【发布时间】:2014-01-10 19:26:52
【问题描述】:

我一定遗漏了一些明显的东西,但以下失败并出现编译错误:

internal static IEnumerable<T> GetEntitiesWithCommaSeparatedRowKeys<T>(
string tableName, string partitionKey, 
string commaDelimitedStringOfRowKeys) where T: TableEntity
{
 ....
    TableQuery<T> entitiesQuery = new TableQuery<T>().Where(
                 TableQuery.CombineFilters(
                           TableQuery.GenerateFilterCondition("PartitionKey",
                           QueryComparisons.Equal, partitionKey),
                           TableOperators.And,
                           AzureHelper.GetFilterConditionForCommaDelimitedStringOfRowKeys(commaDelimitedStringOfRowKeys)
                           ));
    // compile error on this line
    IEnumerable<T> entities = table.ExecuteQuery<T>(entitiesQuery);
 ...
 }

我得到的错误是:

'T' must be a non-abstract type with a public parameterless constructor 
in order to use it as parameter 'TElement' in the generic type or 
method 'Microsoft.WindowsAzure.Storage.Table.CloudTable.ExecuteQuery<TElement>
(Microsoft.WindowsAzure.Storage.Table.TableQuery<TElement>, 
Microsoft.WindowsAzure.Storage.Table.TableRequestOptions, 
Microsoft.WindowsAzure.Storage.OperationContext)'

TableEntity 显然有一个公共的无参数构造函数并且是非抽象的。 以下是我在 TableEntity 上按 F12 时来自元数据信息的对象(只是为了确保它正确解析 TableEntity 类型)。

namespace Microsoft.WindowsAzure.Storage.Table
{

    public class TableEntity : ITableEntity
    {
        // Summary:
        //     Initializes a new instance of the Microsoft.WindowsAzure.Storage.Table.TableEntity
        //     class.
        public TableEntity();
        ...
    }
}

有什么想法吗? 仅供参考,我使用的是 Azure 客户端库 3.0.1.0。

更新:添加 linked issue 解决了类似问题

【问题讨论】:

    标签: c#-4.0 azure-storage azure-table-storage


    【解决方案1】:

    事实证明,如果一个方法对类型提供了约束,那么该约束也必须由该类型的任何调用者转发。

    我不知道。

    在这种情况下,Table.ExecuteQuery 的定义如下所示

     public IEnumerable<TElement> ExecuteQuery<TElement>(TableQuery<TElement> query,
             TableRequestOptions requestOptions = null,
             OperationContext operationContext = null) 
                    where TElement : ITableEntity, new();
    

    因此,将 new() 添加到我的 T 约束可以解决问题。

    所以最终的方法声明看起来像

    internal static IEnumerable<T> GetEntitiesWithCommaSeparatedRowKeys<T>(string tableName,
           string partitionKey,
           string commaDelimitedStringOfRowKeys) 
                  where T : TableEntity , new() //This is new (pun intended :))
    

    在出现此问题的 related links 之一中发现了相关问题。

    我猜编译器总是可以从我实际调用时开始查找类型约束,但由于 TableEntity 是公共的(而不是密封的),我猜它最终可能会成为运行时问题。

    另外有趣的是,我的方法被标记为内部的,这应该真正使编译器能够检查库中的调用者。

    不管怎样,学到了一些新东西:)。

    【讨论】:

    • 感谢分享,是的,它有效。 new() 用于初始化 TElement 泛型的无参数构造函数,该构造函数必须是 TableEntity 类型。这就是为什么在定义继承自 TableEntity 的类时需要一个无参数构造函数的原因。您为我节省了一些故障排除时间,谢谢。
    猜你喜欢
    • 2016-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    相关资源
    最近更新 更多