Коллекция для сохранения Действия с параметром типа - Невозможно преобразовать IEnumerable <dynamic>в IEnumerable <MyEntity> - PullRequest
0 голосов
/ 15 апреля 2020

В следующем классе для Asp. Net http middleware есть метод с параметром типа (ExportResult<T>(...)) и словарь (Exports) для хранения метода с параметрами другого типа.

public class ExportMiddleware : IMiddleware
{
    public Dictionary<string, Func<IEnumerable<dynamic>, string, DataSourceLoadOptionsBase, HttpContext, Task>> Exports => 
        new Dictionary<string, Func<IEnumerable<dynamic>, string, DataSourceLoadOptionsBase, HttpContext, Task>>();

    public ExportMiddleware()
    {
        Exports.Add("download1", (IEnumerable<dynamic> source, string format, DataSourceLoadOptionsBase dataOptions, HttpContext context) =>
                                  ExportResult<MyEntity>(source, format, dataOptions, context)); // Error
                                  // Cannot convert IEnumerable<dynamic> to IEnumerable<MyEntity>
    }

    private async Task ExportResult<T>(IEnumerable<T> source, string format, DataSourceLoadOptionsBase dataOptions, HttpContext context)
    {
        // ....
        // report.DataSource = loadedData.data.Cast<T>();
        // ....
    }

    // Consume the dictionary
    public Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        // ....
        var path = context.Request.Path.ToString();
        if (Exports.TryGetValue(path, out var func))
            return func(source, format, options, context);
        return next(context);
    }
  1. Как устранить ошибку Cannot convert IEnumerable<dynamic> to IEnumerable<MyEntity> на source?
  2. Есть ли способ не использовать dynamic? (нет параметра типа класса)

1 Ответ

1 голос
/ 15 апреля 2020

Если ваш код знает, что source будет IEnumerable<MyEntity>, то приведите его так:

    Exports.Add("download1", (IEnumerable<dynamic> source, string format, DataSourceLoadOptionsBase dataOptions, HttpContext context) =>
                              ExportResult((IEnumerable<MyEntity>)source, format, dataOptions, context));

Если вы хотите использовать шаблон вызова в своем примере, вы можете переместить приведение в ваш помощник по экспорту:

private async Task ExportResult<T>(IEnumerable<dynamic> dynamicSource, string format, DataSourceLoadOptionsBase dataOptions, HttpContext context)
{
    var source = (IEnumerable<T>)dynamicSource;

Если источник на самом деле имеет тип IEnumerable<>, но вы знаете, что все элементы в нем будут иметь тип T, используйте LINQ Cast вместо этого метод:

private async Task ExportResult<T>(IEnumerable<dynamic> dynamicSource, string format, DataSourceLoadOptionsBase dataOptions, HttpContext context)
{
    var source = dynamicSource.Cast<T>();

В любом из этих случаев вы можете подумать, действительно ли dynamic - это то, что вам нужно. Поскольку IEnumerable<> является ковариантным, IEnumerable<object> будет работать так же хорошо во всем коде, которым вы поделились.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...