如何实现一个通用的C#接口。

3

我不太明白我的问题是什么。

CS0452 错误,类型 T 必须是引用类型,以便用作参数...

错误出现在这行代码: Response<T> tableEntity = TC.GetEntity<T>(pk, rk);

using Azure;
using Azure.Data.Tables;

namespace AzureDataTables
{
    public class AzureDataTables<T> : IAzureDataTables<T> where T : class, ITableEntity, new()
    {
        ITableEntity GetTableEntity(string pk, string rk);
    }

    public class AzureDataTables<T> : IAzureDataTables<T> where T : ITableEntity, new()
    {
        public T GetTableEntity(string pk, string rk)
        {
            var tableEntity = TC.GetEntity<T>(pk, rk);
            return tableEntity.Value;
        }
        public TableServiceClient TSC { get; set; } = new TableServiceClient("");
        public TableClient TC => TSC.GetTableClient("");
    }
}


当您将值类型(例如结构或 int)作为参数传递给具有引用类型约束的泛型类型或方法时,会发生此错误。 - Robert Harvey
请尝试将return tableEntity;更改为return tableEntity.Value; - Gaurav Mantri
1
@GauravMantri:那不会起作用。这是一个发生在编译时的错误,在你引用的代码行的上一行发生。 - Robert Harvey
是的,@RobertHarvey那就是我发布的链接。我正在尝试找出如何解决我的问题。 - Terrence
@GauravMantri 很好的观点,但编译器错误在return语句的上一行。TC.GetEntity... - Terrence
3个回答

3

TableClient.GetEntity<T>() 对泛型类型有以下限制:

where T : class, ITableEntity, new();

你的泛型类型也需要添加class约束才能在该函数中使用。

感谢Blindy的协助。我会给@Connor关于修改后的新错误更多的意见。 - Terrence
如果您使用最新的VS 2022、C# 9或10中的任何一个,并添加协变返回类型,那么您的代码将可以直接编译。由于T至少实现了ITableEntity,因此返回T将满足接口要求。 - Blindy

3

如果接口的约定中有一个通用类型,那么在其实现中必须使用具体类型。以下是一个可行的示例:

using Azure;
using Azure.Data.Tables;

namespace AzureDataTables
{
    public interface IAzureDataTables<T> where T : class, ITableEntity, new()
    {
        ITableEntity GetTableEntity(string pk, string rk);
    }

    public class AzureDataTables<T> : IAzureDataTables<T> where T : class, ITableEntity, new()
    {
        public ITableEntity GetTableEntity(string pk, string rk)
        {
            Response<T> tableEntity = TC.GetEntity<T>(pk, rk);
            return tableEntity.Value;
        }

        public TableServiceClient TSC { get; set; } = new TableServiceClient("");
        public TableClient TC => TSC.GetTableClient("");
    }
}


根据您编辑后的问题进行了修改,以下是有关编程的内容的翻译。请仅返回已翻译的文本。 - Bron Davies
谢谢Bron。这就解决了问题。 - Terrence

1
您所调用的方法是TableClient.GetEntity,其有一个约束条件where T : class, Azure.Data.Tables.ITableEntity, new();
而您的方法没有class这个约束条件,因此编译器在检查您的T是否能用于该方法时,发现它不符合所有的约束条件。
如果您更改了:
public class AzureDataTables<T> : IAzureDataTables<T> where T : ITableEntity, new()

To

public class AzureDataTables<T> : IAzureDataTables<T> where T : class, ITableEntity, new()

它将会编译。


谢谢Connor。我已经在OP中更改了我的代码。它卡在这个事实上,即我没有实现接口,因为GetTableEntity没有返回ITableEntity。在泛型方面有些困难,超出了我的能力范围 :) - Terrence

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接