Передать динамический тип данных в функцию - PullRequest
3 голосов
/ 12 августа 2011

У меня есть следующая функция:

private string ParseJson(dynamic q)
    {
        string returnJSON = "[{ \"type\" : \"pie\", \"name\" : \"Campaigns\", \"data\" : [ ";
        foreach (var grp in q)
        {
            double currCount = grp.Count();
            if (grp.Key != null)
                returnJSON += "['" + grp.Key + "', " + currCount + "],";
            else
                returnJSON += "['none', " + currCount + "],";
        }
        returnJSON = returnJSON.Substring(0, returnJSON.Length - 1);
        returnJSON += "]}]";

        return returnJSON;
    }

Я называю это такими методами:

public string GetCampaignData()
    {
        PaymentModelDataContext db = new PaymentModelDataContext();
        var q = from Event in db.TrackingEvents
                group Event by Event.campaignID;


        return ParseJson(q);

    }

Я использую q для нескольких разных запросов, все данные группируются.

Проблема в том, что среда выполнения по какой-то причине не может привязать тип к q. Это правильное использование динамического? Есть ли другой способ сделать это?

1 Ответ

4 голосов
/ 12 августа 2011

Проблема в том, что Count() - это метод расширения, отличный от IEnumerable<T>, поэтому его нельзя вызывать из динамического метода (поскольку это не настоящий метод класса).

Ваша переменная grp также является динамической, поскольку она является результатом выражения для динамической переменной q:

foreach (var grp in q)

Поскольку мы не можем вызывать методы расширения из динамического (опять же, они не являются истинными членами класса), нам нужно явно вызывать метод расширения вместо статического класса Enumerable. Поэтому измените свой код на:

double currCount = Enumerable.Count(grp);

И вы увидите, что он работает правильно для Count(), , если вы действительно хотите использовать dynamic.

Тем не менее, я согласен с комментарием @ Джона о том, что вам следует подумать о том, чтобы изменить его на нединамический. Фактически, то, что принял бы ваш метод, было бы IEnumerable> примерно так:

private string ParseJson<TKey,TValue>(IEnumerable<IGrouping<TKey,TValue>> q)
    {
        string returnJSON = "[{ \"type\" : \"pie\", \"name\" : \"Campaigns\", \"data\" : [ ";
        foreach (var grp in q)
        {
            double currCount = grp.Count();
            if (grp.Key != null)
                returnJSON += "['" + grp.Key + "', " + currCount + "],";
            else
                returnJSON += "['none', " + currCount + "],";
        }
        returnJSON = returnJSON.Substring(0, returnJSON.Length - 1);
        returnJSON += "]}]";

        return returnJSON;
    }

Вы также можете сделать тип параметра не универсальным, специфичным для вашего использования, если хотите. Но это будет работать со всеми группировками ...

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