Как да осъществя достъп до свойството count от динамичен тип в C# 4.0?

Имам следния метод, който връща динамичен обект, представляващ IEnumerable<'a> ('a=анонимен тип):

    public dynamic GetReportFilesbyStoreProductID(int StoreProductID)
    {
        Report report = this.repository.GetReportByStoreProductID(StoreProductID);

        if (report == null || report.ReportFiles == null)
        {
            return null;
        }

        var query = from x in report.ReportFiles
                    orderby x.DisplayOrder
                    select new { ID = x.RptFileID, Description = x.LinkDescription, File = x.LinkPath, GroupDescription = x.ReportFileGroup.Description };

        return query;
    }

Искам да имам достъп до свойството Count на този IEnumerable анонимен тип. Опитвам се да осъществя достъп до горния метод, като използвам следния код и не успявам:

        dynamic Segments = Top20Controller.GetReportFilesbyStoreProductID(StoreProductID");

        if (Segments.Count == 0)  // <== Fails because object doesn't contain count.
        {
            ...
        }
  • Как функционира ключовата дума dynamic?
  • Как мога да получа достъп до свойството Count на анонимния тип IEnumerable?
  • Има ли начин да използвам този анонимен тип или трябва да създам персонализиран обект, за да мога да предам обратно строго въведено IEnumerable<myObject> вместо dynamic?

Бих предпочел да не правя това, ако мога, тъй като този метод се извиква само на едно място и създаването на обект за изхвърляне изглежда като излишно.


person Rodney    schedule 08.06.2011    source източник
comment
Трябва силно да обмислите създаването на реални типове вместо анонимни типове и да върнете IEnumerable от това. Използването на dynamic за тази цел унищожава всички предимства на статичното писане.   -  person Kirk Woll    schedule 09.06.2011
comment
Отчетите на @Kirk могат да бъдат динамични? не точно в този случай, но все пак   -  person Bas    schedule 09.06.2011
comment
Когато дефинирате еднократен тип само за да се върнете от метод, има много малко, ако изобщо има предимства пред статичното писане.   -  person mqp    schedule 09.06.2011
comment
@Kirk, този персонализиран обект би бил обект за изхвърляне, който се използва веднъж. Ще има ли по-добър вариант от изграждането на цял клас, който да се използва еднократно?   -  person Chev    schedule 09.06.2011
comment
@Chevex, ако OP връща тази стойност от публичен метод, не разбирам защо смятаме, че ще бъде извикан само веднъж.   -  person Kirk Woll    schedule 09.06.2011
comment
@kirk, добре, имам специално прозрение, тъй като той е мой колега. Ще бъде извикан само веднъж.   -  person Chev    schedule 09.06.2011
comment
@mquander, напълно не съм съгласен, че няма предимства за статичното писане дори в еднократни ситуации. Ако предлагате, би било хубаво, ако можете да върнете анонимни типове (като този тип) от метод, съгласен съм! Но не можеш. И статичното писане е все още безкрайно полезно в тази ситуация. (intellisense, безопасност по време на компилиране и т.н.)   -  person Kirk Woll    schedule 09.06.2011
comment
Тук трябва да се съглася с @Kirk. Ако този метод беше частен, връщането на последователност от анонимен тип динамично е разумно. Все пак е публично.   -  person TrueWill    schedule 09.06.2011
comment
@Вярно, за да не споря, но не мисля, че динамично трябва никога да се използва за свързване на анонимен тип. Никога не трябва да се използва, защото човек е твърде мързелив, за да създаде правилен тип. Трябва да се използва за отражение, или динамично изпращане, или COM, или динамични скриптове.   -  person Kirk Woll    schedule 09.06.2011
comment
Ако забележите, той не пита как трябва да се използва. Той пита как да използва динамика в този случай. Дали това е правилният избор или не е без значение. Вероятно така или иначе ще го напише статично, но отговорът на въпроса все още е интересен.   -  person Chev    schedule 09.06.2011
comment
@Chevex, да и затова това са коментари, а не отговори. :)   -  person Kirk Woll    schedule 09.06.2011
comment
Намирам за необичайно, че хората са толкова придирчиви кога dynamic се използва и кога не се използва; Справям се добре с писането на Javascript, Clojure и др., където (аха) всичко е динамично! Съгласен съм обаче, че не е идиоматично C# да се използва dynamic в тази ситуация. Аз лично бих направил еднократен именуван тип или бих преместил нещата, за да премахна необходимостта от това.   -  person mqp    schedule 09.06.2011
comment
@mquander, по тази логика, защо не се откажете от var и наименуваните типове и не използвате dynamic за всяка декларация на тип, която имате?   -  person Kirk Woll    schedule 09.06.2011
comment
@Kirk - срещнах един сценарий, в който има смисъл. Имате ДЪЛЪГ оператор Link-to-Objects, който използва анонимни типове за съединения (поради равенството на свойствата). Искате да преработите това, но не можете да извлечете метод поради анонимните типове. Трябва не само да създадете клас, но и да замените Equals и GetHashCode.   -  person TrueWill    schedule 09.06.2011
comment
@Kirk: Тъй като полученият език C#-без-типове би бил гаден в сравнение с други съвременни динамични езици и подозирам, че ще се окаже, че ще се представи лошо и в сравнение. Това обаче всъщност не е аргумент срещу изолираните употреби на dynamic за заобикаляне на неудобни части от C#.   -  person mqp    schedule 09.06.2011


Отговори (5)


IEnumerable<T>, който се връща от този метод, няма свойството Count, така че не знам за какво говорите. Може би сте забравили да напишете ToList() в края, за да го превърнете в списък, или сте искали да извикате метода Count() на IEnumerable<T>?

person mqp    schedule 08.06.2011
comment
Може да няма статично свойство Count, но има разширение Count() LINQ. Мисля, че мисълта му е, че той не знае как да използва динамичния обект, който се връща. - person Chev; 09.06.2011
comment
Е, той би го използвал правилно, ако случайно се позоваваше на свойство или метод, които действително съществуват, така че трябва просто да е объркал нещо. - person mqp; 09.06.2011
comment
А, вярно, ще го информирам да добави скоби към повикването за преброяване. - person Chev; 09.06.2011

Ще трябва изрично да извикате Enumerable.Count().

IEnumerable<string> segments =
  from x in new List<string> { "one", "two" } select x;

Console.WriteLine(segments.Count());  // works

dynamic dSegments = segments;

// Console.WriteLine(dSegments.Count());  // fails

Console.WriteLine(Enumerable.Count(dSegments));  // works

Вижте Метод на разширение и динамичен обект в c# за дискусия защо разширение методите не се поддържат от динамично въвеждане.

(Префиксът „d“ е само за примерния код – моля, не използвайте унгарска нотация!)

Актуализация: Лично аз бих избрал Отговорът на @Magnus за използване на if (!Segments.Any()) и връщане на IEnumerable<dynamic>.

person TrueWill    schedule 08.06.2011
comment
+1 Напълно забравих за съображенията при използване на Dynamics. Наистина се чудя как работи приетият отговор. Благодаря все пак - person iam.Carrot; 21.04.2017
comment
перфектно.. +++++++ - person Thameem; 24.07.2019

Count() трябва да изброи, за да завърши събирането, вероятно искате:

if (!Segments.Any()) 
{
}

И вашата функция трябва да върне IEnumerable<object> вместо динамично

person Magnus    schedule 08.06.2011
comment
+1 - Трябваше да го пробвам, но това работи. Въпреки че подозирам, че OP ще иска да върне IEnumerable‹dynamic›, за да стигне до свойствата на анонимния тип. - person TrueWill; 09.06.2011

Опитайте Linq countusing System.Linq; Segments.Count()

person Bas    schedule 08.06.2011

Можете също да използвате свойството Length!

if (!Segments.Length)
{
    `enter code here`
}
person alvescleiton    schedule 31.07.2019