Czy wszystkie obiekty wyjątków .NET mogą zostać przekształcone do postaci szeregowej?Czy są możliwe wszystkie serializery .NET?
Odpowiedz
Tak i nie. Jak zauważyli Jeff i inni, wszystkie klasy wyjątków powinny i prawie zawsze podlegać serializacji. Jeśli natkniesz się na określoną klasę wyjątków, której nie można poddać serializacji, jest to prawdopodobnie błąd.
Jednak rozważając możliwość serializacji, należy wziąć pod uwagę zarówno bezpośrednią klasę, jak i wszystkie typy, które są członkami tego typu (jest to proces rekurencyjny). Podstawowa klasa wyjątków ma właściwość Data, która jest typu IDictionary. Jest to problematyczne, ponieważ pozwala użytkownikowi lub kogokolwiek innego dodać dowolny obiekt do wyjątku. Jeśli ten obiekt nie jest możliwy do serializacji, serializacja wyjątku zakończy się niepowodzeniem.
Domyślna implementacja właściwości Data wykonuje pewne podstawowe sprawdzenia, aby zapewnić, że dodawany obiekt jest poddawany serializacji. Ale to jest wadliwy na kilka sposobów
- Tylko ma najwyższy poziom sprawdzania serializability typu i tej kontroli odbywa się tylko poprzez sprawdzenie Type.IsSerializable (nie 100% stały wyboru).
- Własność jest wirtualna. Typ wyprowadzonego wyjątku może przesłonić i użyć tablicy HashTable, która wykonuje 0 sprawdzania.
System.Exception
implementuje ISerializable
i jest klasą podstawową dla wszystkich wyjątków, więc tak.
Patrz: http://msdn.microsoft.com/en-us/library/system.exception.aspx
Tak, ale historycznie nie było (gra słów nie przeznaczonych) wyjątki.
Innymi słowy, wszystkie wyjątki powinny być serializable, ale niektóre niestandardowe Wyjątki od kodu strony trzeciej nie możebyć, w zależności od tego, jak są one realizowane.
Na przykład w erze .NET 1.0 wyjątki od oficjalnego dostawcy bazy danych Microsoft Oracle nie podlegały szeregowaniu z powodu błędów w ich kodzie.
Nawet od .Net 4.5, niektóre wyjątki bazy danych OleDB i niektóre wyjątki System.Net nie podlegają de-serializacji z powodu braku wymaganego konstruktora. – ricovox
System.Exception
implementuje ISerializable
, ale potomkowie mogą nie deserializować, jeśli nie implementują poprawnego przeciążonego konstruktora z podpisem (SerializationInfo,StreamingContext)
.
Ponadto, jeśli wyprowadzony wyjątek nie wywołuje poprawnie base.GetObjectData, informacje o podstawowym wyjątku nie zostaną przekształcone do postaci szeregowej, co spowodowałoby błędy przy dekompresji. W obu przypadkach (brakujący konstruktor lub brak serializacji bazy), serializacja zakończy się pomyślnie, ale dekompresja spowoduje zgłoszenie wyjątku. – ricovox
Ta kwestia została już odpowiedział wystarczająco, ale dla programistów, którzy są nowi w C# lub serializacji, myślę, że to jest rzeczywiście bardzo pomocne, aby podkreślić, że w ogóle, Wyjątkiem są NIE serializable!
To może zabrzmieć nieco prowokacyjnie, ale pozwól mi wyjaśnić.
To prawda, że wszystkie wyjątki implementują interfejs ISerializable, ale sugeruje to tylko, że numer powinien być możliwy do przekształcenia w postaci. Ale implementacja interfejsu NIE powoduje, że obiekt jest Serializowalny (co w tym kontekście oznacza, że Wyjątek może być zarówno serializowany i deserializowany).
Najbardziej dokładną odpowiedzią na to pytanie, jak zauważyli inni, jest to, że wiele, ale z pewnością nie wszystkie wyjątki w .Net Framework są Serializowalne.Ale jeśli pytanie używa terminu ".NET Exception" w szerszym zakresie, np. Wyjątek: uzyskany od System.Exception, następnie lepszą i bardziej pomocną odpowiedzią, jeśli chodzi o najlepsze praktyki i unikanie błędów, jest stwierdzenie powyżej, że w ogóle Wyjątki nie są Serializowalne.
Oto dlaczego: Jak już wcześniej wspomniano, aby wyjątek był naprawdę możliwy do Serializacji, musi mieć właściwego konstruktora ctor(SerializationInfo, StreamingContext)
i musi być ozdobiony odpowiednim atrybutem. Co ważne, żadne z tych ograniczeń nie powoduje błędów kompilatora, jeśli zostały pominięte!
Co oznacza, że klasa NO pochodząca z wyjątku jest możliwa do przeprowadzenia Serializacji, chyba że zostaną podjęte dodatkowe, opcjonalne (z punktu widzenia kompilatora) kroki.
tj. każdy nieseryjny/nieświadomy programista, który wyprowadza nowy wyjątek, jak poniżej, właśnie stworzył wyjątek, który NIE jest Serializowalny.
class MyNewException : Exception { }
Visual Studio ma świetny "wyjątek", który pozwala szybko generować nowe wyjątki serializowalne. Ale nawet w tym przypadku nic nie przypomina ani nie pomaga programistom w rzeczywistych seriach właściwości obiektu. Na przykład, nawet jeśli poniższa klasa ma odpowiedni konstruktor i atrybut, właściwość MyNewField
nie będzie serializowana bez dodatkowego kodu zarówno w konstruktorze, jak iw GetObjectData.
class MyNewException : Exception
{
public MyNewField { get; set; }
}
Tak więc, głównym punktem jest to, że jeśli trzeba polegać na właściwej serializacji Exception & deserializacji z jakiegoś powodu powinny być całkowicie świadomi, że jeśli chodzi o jakiegokolwiek kodu niestandardowego lub zespołów, nie ma gwarancji, że będzie działać. Ponadto, ponieważ wymagany konstruktor jest zwykle chroniony, niekoniecznie będzie można łatwo sprawdzić, czy jest on obecny (bez refleksji).
W moich własnych projektach w niektórych punktach stworzyłem wyjątek "Serwery proxy", który może przechowywać niektóre informacje (np. Wiadomość itp.) Z Wyjątków, które same nie są przekształcalne. Mogą one służyć do serializowania niektórych informacji lub alternatywnie do deserializacji danych zapisanych przez wyjątek, który nie ma odpowiedniego konstruktora.
- 1. Czy są jakieś .NET ESB?
- 2. .NET Overload WebMethods - Możliwe?
- 3. Czy możliwe są asynchroniczne zapytania modelu Django?
- 4. Czy są możliwe testy typu rodzinnego?
- 5. Highcharts: czy możliwe są różne legendy?
- 6. Czy filtry niestandardowe w NUnit są możliwe?
- 7. Czy exploity przepełnienia bufora są możliwe w języku C#?
- 8. algorytm wyliczyć wszystkie możliwe ścieżki
- 9. Czy wszystkie porównania równości PHP są symetryczne?
- 10. , aby sprawdzić, czy wszystkie EditText są puste
- 11. Sprawdź, czy wszystkie obrazy są ładowane
- 12. Sprawdź, czy wszystkie znaczniki są zamknięte
- 13. C# - czy wszystkie są stałe Enum?
- 14. Sprawdzanie, czy wszystkie zmienne POST są ustawione
- 15. Czy konieczne są wszystkie konstruktory std :: tuple?
- 16. wygenerować wszystkie możliwe kombinacje - Java
- 17. Czy są jakieś implementacje multiset dla .Net?
- 18. Czy tablice w .NET są naturalnie wyrównane?
- 19. Czy finalizatory .net są zawsze wykonywane?
- 20. Czy "out" parametry są złe w .NET?
- 21. Czy są gotowe biblioteki biblioteki memo .NET?
- 22. Jak wygenerować wszystkie możliwe kombinacje?
- 23. wszystkie możliwe kombinacje n zestawów
- 24. Wszystkie wbudowane atrybuty .Net
- 25. Czy możliwe są zależne od pobrania żądania w Github?
- 26. IDataErrorInfo: Jak sprawdzić, czy wszystkie właściwości są prawidłowe?
- 27. Czy jest możliwe, aby uzyskać wszystkie wspólne apache na raz?
- 28. Czy jest możliwe dziedziczenie wielokrotne w VB .Net?
- 29. Czy w Protobuf-net możliwe jest serializowanie nieprzypisanych klas?
- 30. Czy jest możliwe, aby projekt C# używał wielu wersji .NET?
Oprócz tego, że klasy pochodne nie dziedziczą SerializableAttribute, więc każda klasa pochodna musi być również dekorowana, aby klasa mogła być poddawana szeregowaniu. – GalacticCowboy