繁体   English   中英

在 C# 中,如何将接口转换为扩展接口的接口?

[英]In C#, how can I cast an interface to an interface which extends the interface?

我有几个接口:

    public interface ILockable
    {
        public string LockToken { get; set; }
    }

    interface ILockableSalesforceRecord : ILockable, ISalesforceRecordable
    {
    }

    public interface IServiceBusMessageReceiver
    {
        Task DoWithAsync<T>(IQueueConfig queueConfig, Func<List<ILockable>, Task<bool>> function)
            where T : ILockable;
    }

我有一个带有这个签名的方法:

private async Task<bool> WriteToSalesforceCacheAsync<T>(List<ILockableSalesforceRecord> eventBusRecords, CancellationToken cancellationToken)

我想通过以下方法将其传递给最后一个接口的具体化:

        public async Task WriteToSalesforceCacheAsync<T>(IQueueConfig queueConfig, CancellationToken cancellationToken)
            where T : ISalesforceRecordable
        {
            await _serviceBusQueueReceiver.DoWithAsync<T>(queueConfig, async records =>
            {
                return await WriteToSalesforceCacheAsync<T>((List<ILockableSalesforceRecord>)records, cancellationToken)
                    .ConfigureAwait(false);
            });
        }

但这无法编译:

Severity Code Description Project File Line Suppression State Error CS0030 Cannot convert type 'System.Collections.Generic.List<Enpal.Messaging.ILockable>' to 'System.Collections.Generic.List<Enpal.AzureServiceBusToSfCacheTranscriber.Models.ILockableSalesforceRecord>' Enpal. AzureServiceBusToSfCacheTranscriber C:\projects\AzureServiceBusToSfCacheTranscriber\AzureServiceBusToSfCacheTranscriber\Helpers\RelayHelper.cs 38 活动

我可以/应该做些什么来解决这个问题?

在您的界面中,您声明了一个通用参数T ,但实际上并未在 arguments 中使用它。

您可能打算这样设计它:

public interface IServiceBusMessageReceiver
{
    Task DoWithAsync<T>(IQueueConfig queueConfig, Func<List<T>, Task<bool>> function)
        where T : ILockable;
}

此外,使用您的方法WriteToSalesforceCacheAsync ,您再次声明T ,但看起来您现在正在使用特定类型(即ILockableSalesforceRecord ),因此可以删除T

private async Task<bool> WriteToSalesforceCacheAsync(
    List<ILockableSalesforceRecord> eventBusRecords, CancellationToken cancellationToken)
{
    //...
}

public async Task WriteToSalesforceCacheAsync(
    IQueueConfig queueConfig, CancellationToken cancellationToken)
{
    await _serviceBusQueueReceiver.DoWithAsync<ILockableSalesforceRecord>(queueConfig, 
    async records =>
    {
        return await WriteToSalesforceCacheAsync(records, cancellationToken)
            .ConfigureAwait(false);
    });
}

现在,因为ILockableSalesforceRecord作为通用参数提供给DoWithAsyncWriteToSalesforceCacheAsync随后被传递一个List<ILockableSalesforceRecord>并且代码编译: https://dotnetfiddle.net/5Bz7SS


顺便说一句,您不应该依赖接口签名中的特定集合类型,例如List<T> ,因为这对客户端有限制; 而是使用依赖于要求的接口类型,例如IEnumerable<T>ICollection<T>等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM