Mam do czynienia z ideą uczynienia prymitywnych typów wartości .NET bardziej bezpiecznymi i bardziej "samokomponującymi" poprzez zawinięcie ich w niestandardowe struct
s. Zastanawiam się jednak, czy w rzeczywistości jest to warte wysiłku w prawdziwym oprogramowaniu.Typowe prymitywne typy wartości .NET za pomocą niestandardowych struktur: czy to jest warte wysiłku?
(That „wysiłek” można zobaczyć poniżej. Mając ponownie i ponownie zastosować ten sam kod wzoru Jesteśmy deklarując
struct
s, a więc nie można użyć dziedziczenia do usunięcia kodu powtórzenia, a od przeciążonych operatorów należy uznać zastatic
, muszą być określone dla każdego typu osobno)
Weź to (co prawda trywialne) przykład:.
struct Area
{
public static implicit operator Area(double x) { return new Area(x); }
public static implicit operator double(Area area) { return area.x; }
private Area(double x) { this.x = x; }
private readonly double x;
}
struct Length
{
public static implicit operator Length(double x) { return new Length(x); }
public static implicit operator double(Length length) { return length.x; }
private Length(double x) { this.x = x; }
private readonly double x;
}
Zarówno Area
, jak i Length
są w zasadzie double
, ale rozszerzają je o określone znaczenie. Jeśli zdefiniowałeś metodę taką jak & hellip;
Area CalculateAreaOfRectangleWith(Length width, Length height)
& hellip; nie byłoby możliwe, aby bezpośrednio przejść w Area
przez przypadek. Jak na razie dobrze.
ALE: można łatwo ominąć to najwyraźniej poprawiła bezpieczeństwo typu po prostu przez odlewanie Area
do double
lub poprzez tymczasowe przechowywanie e Area
w zmiennej double
, a następnie przechodząc że do metody, gdzie oczekiwany jest Length
:
Area a = 10.0;
double aWithEvilPowers = a;
… = CalculateAreaOfRectangleWith((double)a, aWithEvilPowers);
Pytanie: Czy ktoś tutaj ma doświadczenie z szerokim wykorzystaniem takiego zwyczaju struct
typów w świecie rzeczywistym/software produkcja? Jeśli tak, to:
Czy owijanie w prymitywnych typów wartości niestandardowych
struct
s kiedykolwiek bezpośrednio spowodowało mniej błędów, lub w kodzie bardziej zarządzalny, czy dana żadnego innego znaczącą przewagę (y)?A może korzyści z niestandardowych
struct
są zbyt małe, aby można je było wykorzystać w praktyce?
P.S .: Około 5 lat minęło od czasu, kiedy zadał to pytanie. Zamieszczam some of my experiences that I've made since then jako osobną odpowiedź.
** P.S.: ** Jestem świadomy, że jeden może być w stanie pozbyć się jednej z dwóch opisanych technik sidestepping, definiując 'Area -> double' cast operator 'explicit' zamiast' implicit'. – stakx
Prawdopodobnie nie myślę wystarczająco duże, ale czy zauważyłeś, że ten rodzaj błędu pojawia się bardzo często dla Ciebie? To znaczy - kiedy masz dane z zewnętrznego źródła (być może bez typu) i do twojego programu, będzie ono w jakiejś strukturze, w której dostęp do niej ma pewne imię, które ma sens jak "object.length". Zazwyczaj nie kończysz na podawaniu liczb surowych, ale raczej przekazujesz struktury. Pomyślałbym, że ten rodzaj błędu jest rzadki, nie mogę myśleć o tym, by mnie wymyślić. –
Podejrzewam, że ten typ błędu nie zdarza mi się często, @jamietre, ale nie mam żadnych twardych statystyk do poparcia lub odrzucenia tego założenia. Istnieją jednak inne potencjalne korzyści; łatwiejszy do zrozumienia kod może być jednym z nich. Po prostu nie jestem pewien z góry, jeśli to uzasadnia konieczność implementacji wielu bardzo podobnych typów 'struct' ... – stakx