Operacja może zdestabilizować runtime?

Mam mały problem ze zrozumieniem, w czym tkwi problem. Mam trochę kodu, który pobiera rekordy z bazy danych za pomocą LINQ i umieszcza je w obiekcie, który jest odlewany w interfejsie. Wygląda to trochę tak:

public IEnumerable<ISomeObject> query()
{
    return from a in dc.SomeTable
           select new SomeObject
           {
             //Assign various members here
           } as ISomeObject;
}

Kiedy to testuję, umieszczam zwracaną liczbę IEnumerable w zmiennej o nazwie results i uruchamiam tę linię:

Assert.AreEqual(EXPECTED_COUNT, results.Count());
Kiedy to jest uruchomione, dostaję System.Ochrona.VerificationException: "operacja może destabilizować runtime."

I znalazłem rozwiązanie tutaj , czyli to:

var results = from a in dc.SomeTable
              select new SomeObject
              {
                //Assign various members here
              } as ISomeTable;
return results.OfType<ISomeObject>();
To działa, ale mam problem ze zrozumieniem, co się tu dzieje. Dlaczego w pierwszej kolejności otrzymałem wyjątek i w jaki sposób powyższe linie kodu go naprawiły? Dokumentacja MSDN wydaje się sugerować, że jest to kwestia bezpieczeństwa typu, ale nie widzę, gdzie poprzedni kod był niebezpieczny dla typu.

UPDATE Trochę więcej informacji dowiedziałem się. Pierwszy przykład działa, jeśli dokonam typu return IQueryable. To rzuca trochę więcej światła na Co poszło źle, ale nadal jestem zdezorientowany dlaczego . Dlaczego kompilator nie zmusił mnie do wrzucenia liczby mnogiej do IQueryable?

Author: Jason Baker, 2008-12-18

10 answers

Uważam, że jest to kwestia kowariancji lub kontrawariancji, jak zauważył ten post na forum .

Zobacz kowariancję i Kontrawarancję w C#, Część druga: kowariancję tablicy i resztę serii kowariancję i Kontrawarancję na blogu Erica Lipperta.

Chociaż zajmuje się tablicami w artykule, który podlinkowałem, uważam, że podobny problem pojawia się tutaj. W pierwszym przykładzie zwracasz IEnumerable, który może zawierać obiekty, które zaimplementuj interfejs, który jest większy niż ISomeTable (np.-możesz umieścić żółwia w zwierzęciu, które może zawierać tylko żyrafy). Myślę, że to działa po powrocie IQueryable dlatego, że jest to większe / szersze niż cokolwiek, co możesz zwrócić, więc masz gwarancję, że to, co zwrócisz, będziesz w stanie obsłużyć(?).

W drugim przykładzie OfType {[5] } zapewnia, że to, co zostanie zwrócone, jest obiektem, który przechowuje wszystkie informacje niezbędne do zwrócenia tylko tych elementów, które można oddać żyrafie.

Jestem prawie pewien, że ma to coś wspólnego z kwestiami bezpieczeństwa typu opisanymi powyżej, ale jak mówi Eric Lippert funkcje wyższego rzędu szkodzą mojemu mózgowi i mam problem z dokładnym wyjaśnieniem, dlaczego jest to problem Ko/sprzeczny.

 19
Author: Grant Wagner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-18 20:15:54

Znalazłem ten wpis szukając własnego rozwiązania "operacja może zdestabilizować runtime". Chociaż powyższa porada dotycząca kowariancji / kontra-wariancji wygląda bardzo interesująco, w końcu odkryłem, że otrzymuję ten sam komunikat o błędzie, uruchamiając moje testy jednostkowe z włączonym pokryciem kodu i zestawem atrybutów allowpartialt Trustedcallers.

Usunięcie atrybutu AllowPartiallyTrustedCallers spowodowało, że moje testy działały poprawnie. mogę również wyłączyć pokrycie kodu, aby one uruchomić, ale to nie było akceptowalne rozwiązanie.

Miejmy nadzieję, że pomoże to komuś innemu, kto trafi na tę stronę, próbując znaleźć rozwiązanie tego problemu.

 12
Author: Ira Miller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-21 15:23:31

Tylko zgaduję, ale operator as może zwracać null - więc może mieć to związek z rzeczywistą implementacją kodu new SomeObject { ... }, ponieważ jest cukrem składniowym. Filtry return results.OfType<ISomeTable>(); oparte na typie, więc instrukcja return metody zwróci tylko ten typ (zapewniając bezpieczeństwo typu). Napotkałem podobny problem ze zwracaniem typów generycznych.

P. S. podoba mi się " operacja może zdestabilizować runtime."wyjątek. To prawie jak " możesz wysadzić internet" wyjątek.

 5
Author: Zachary Yates,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-18 19:29:52

Natknąłem się na ten błąd z podobnym kodem;

IEnumerable<Table> records = (from t in db.Tables
                              where t.Id.Equals(1)
                              select t).ToList();

Ten pozornie nieszkodliwy kod był częścią metody UserControl, która została wywołana ze strony. Nie ma problemu w środowisku programistycznym. NET4, jednak gdy strona była wstępnie skompilowana i wdrożona na serwerze na .NET3.5 dostałem ten błąd.

Podejrzewam, że ma to coś wspólnego z faktem, że kontrola była kompilowana do oddzielnej biblioteki DLL w połączeniu ze zmianami zabezpieczeń między frameworkami, jak opisano w this. Net security blog

Moje rozwiązanie: Uruchom witrynę live na .NET4

 2
Author: Red Taz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-11 08:45:18

Czy nadal nie działa, jeśli to zmienisz:

select new SomeObject { ... } as ISomeTable;

Do tego:

select (ISomeTable) new SomeObject { ... };

?

Jeśli tak (jak widzę potwierdzasz), może ma to związek z faktem, że implementacja interfejsu może być klasą lub strukturą? Czy problem nadal pojawia się, jeśli rzucisz do klasy abstrakcyjnej, a nie interfejsu?

 0
Author: Av Pinzur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-18 19:50:13

Odkryłem, że OfType ma pewne nieprzyjemne skutki uboczne podczas korzystania z linq do sql. Na przykład, części linq, które zostały wcześniej ocenione po uruchomieniu zapytania z db, zostały zamiast tego przetłumaczone na SQL. Nie powiodło się to, ponieważ te sekcje nie miały odpowiednika SQL. Skończyło się na zażywaniu .Zamiast tego obsada, która wydaje się również rozwiązywać problem.

 0
Author: LaserJesus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-05 02:51:44

W moim przypadku błędnie zadeklarowałem właściwość Storage w atrybucie kolumny klasy Linq2SQL

    [Column(Storage = "_Alias", DbType = "NVarChar(50)")]
    public string UserAlias
 0
Author: user1760527,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-20 07:59:46

Miałem ten sam problem, ale z dziedziczeniem Zdefiniowałem klasę w assembly A i podklasę w Assembly B po dodaniu poniższego atrybutu do assembly A, problem rozwiązany:

[assembly: SecurityRules(SecurityRuleSet.Level1, SkipVerificationInFullTrust = true)]
 0
Author: Homayoun Behzadian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-02 20:25:56

Napotkałem ten błąd podczas korzystania z " Dynamic data access framework "Passive library . Źródłem błędu była linia 100 W DynamicDatabase.plik cs.

databaseDetectors = (databaseDetectors ?? Enumerable.Empty<DatabaseDetector>()).DefaultIfEmpty(new DatabaseDetector());

Zmieniłem linijkę kodu na:

databaseDetectors = (databaseDetectors ?? Enumerable.Empty<DatabaseDetector>()).DefaultIfEmpty(new DatabaseDetector()).OfType<IDatabaseDetector>();
W ten sposób rozwiązano problem. Poszedłem dalej i rozwidlałem projekt i przesłałem zmianę oryginalnemu autorowi. Dziękuję Ci, Jasonie Baker, za wskazanie rozwiązania w Twoim pierwotnym pytaniu.

Na marginesie, oryginał biblioteka działała dobrze na moim komputerze lokalnym i na VPS Rackspace, ale kiedy pchnąłem ten sam kod do współdzielonego środowiska hostingu (GoDaddy i witryny w chmurze Rackspace), zacząłem otrzymywać błąd "operacja może zdestabilizować runtime".

 0
Author: Tod Birdsall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-06 15:01:01

Domyślam się, że Linq do Sql może nie obsługiwać castingu przy tłumaczeniu na polecenie sql.

 -4
Author: Chaowlert Chaisrichalermpol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-18 21:00:17