Bør jeg gjøre for at argumentene er ikke null før du bruker dem i en funksjon?

stemmer
6

Tittelen kan egentlig ikke forklare hva jeg egentlig prøver å få til, kunne egentlig ikke tenke på en måte å beskrive hva jeg mener.

Jeg lurte på om det er lurt å sjekke de argumentene som en funksjon aksepterer for nullverdier eller tom før du bruker dem. Jeg har denne funksjonen som bare brytes litt hasj skapelse som så.

Public Shared Function GenerateHash(ByVal FilePath As IO.FileInfo) As String
        If (FilePath Is Nothing) Then
            Throw New ArgumentNullException(FilePath)
        End If

        Dim _sha As New Security.Cryptography.MD5CryptoServiceProvider
        Dim _Hash = Convert.ToBase64String(_sha.ComputeHash(New IO.FileStream(FilePath.FullName, IO.FileMode.Open, IO.FileAccess.Read)))
        Return _Hash
    End Function

Som du kan se jeg bare tar en IO.Fileinfo som et argument, i starten av funksjonen jeg sjekker for å forsikre deg om at det ikke er noe.

Jeg lurer på er dette god praksis eller skal jeg bare la det komme til selve hasher og deretter kaste unntak fordi det er null.?

Takk.

Publisert på 13/10/2008 klokken 22:30
kilden bruker
På andre språk...                            


10 svar

stemmer
1

Hvis NULL er en uakseptabel inngang, kaste et unntak. Av deg selv, som du gjorde i prøven, slik at budskapet er nyttig.

En annen fremgangsmåte for å håndtere NULL innganger er bare for å respont med en NULL etter tur. Avhenger av type funksjon - i eksempelet ovenfor jeg ville holde unntaket.

Svarte 13/10/2008 kl. 22:33
kilden bruker

stemmer
1

Hvis det er for et eksternt ut mot API så ville jeg si at du ønsker å sjekke hver parameter som inngangs ikke kan stole på.

Men hvis det bare kommer til å bli brukt internt så inngangen bør være i stand til å stole på, og du kan spare deg selv en haug med kode som ikke tilfører verdi til programvaren.

Svarte 13/10/2008 kl. 22:36
kilden bruker

stemmer
20

Generelt vil jeg foreslå det er god praksis å validere alle argumentene til offentlige funksjoner / metoder før du bruker dem, og mislykkes tidlig heller enn etter å utføre halvparten av funksjonen. I dette tilfellet, du har rett til å kaste unntaket.

Avhengig av hva metoden gjør, kan sviktende tidlig være viktig. Hvis metoden ble endre eksempel data om klassen din, trenger du ikke vil at den skal endre halvparten av dataene, så møter null og kaste et unntak, som objektets data kan dem være i en mellom og muligens ugyldig tilstand.

Hvis du bruker en OO språk så jeg foreslår at det er viktig å validere argumentene til offentlige metoder, men mindre viktig med private og beskyttede metoder. Min begrunnelse her er at du ikke vet hva inngangene til en offentlig metode vil være - en annen kode kan opprette en forekomst av klassen og kaller det offentlige metoder, og pass på uventede / ugyldige data. Private metoder, derimot, kalles fra inne i klassen, og klassen skal allerede ha godkjent alle data som passerer rundt internt.

Svarte 13/10/2008 kl. 22:39
kilden bruker

stemmer
0

Mesteparten av tiden, slik at det bare kaste unntak er ganske rimelig, så lenge du er sikker på at unntaket ikke vil bli ignorert.

Hvis du kan legge noe til det, men det skader ikke å vikle unntak med en som er mer nøyaktig og rethrow det. Dekoding "NullPointerException" kommer til å ta litt lenger tid enn "IllegalArgumentException (" Filbane MÅ leveres ")" (eller hva).

I det siste har jeg jobbet på en plattform der du må kjøre en obfuscator før du testen. Hver stabel spor ser ut som aper skrive tilfeldig crap, så jeg fikk i vane å sjekke mine argumenter hele tiden.

Jeg vil gjerne se en "nullable" eller "nonull" modifier på variabler og argumenter slik at kompilatoren kan sjekke for deg.

Svarte 13/10/2008 kl. 22:39
kilden bruker

stemmer
2

Ja, det er god praksis å validere alle argumenter i begynnelsen av en metode og kaste passende unntak som ArgumentException, ArgumentNullException eller ArgumentOutOfRangeException.

Hvis metoden er privat slik at bare du programmerer kunne passere ugyldige argumenter, så kan du velge å hevde hvert argument er gyldig (Debug.Assert) i stedet for innkast.

Svarte 13/10/2008 kl. 22:40
kilden bruker

stemmer
3

En av mine favoritt teknikker i C ++ var å DEBUG_ASSERT på NULL pekere. Dette ble boret inn i meg av senior programmerere (sammen med konst korrekthet) og er en av de tingene jeg var mest strenge på under kodegjennomgang. Vi aldri dereferenced en peker uten først å hevde at det ikke var null.

En debug hevde er bare aktiv for avlusing mål (det blir strippet i release), slik at du ikke trenger den ekstra overhead i produksjonen for å teste for tusenvis av hvis tallet. Vanligvis ville det enten kaste et unntak eller utløse en hardware stoppunkt. Vi hadde systemer som ville kaste opp en debug-konsoll med filen / line info og en mulighet til å ignorere hevde (en gang eller på ubestemt tid for økten). Det var en så stor feilsøke og QA verktøy (vi ville få skjermbilder med hevde på testere skjermen og informasjon om programmet fortsatte dersom ignorert).

Jeg foreslår å hevde alle invarianter i koden din, inkludert uventede nuller. Hvis resultatene av If blir en bekymring finne en måte å betinget kompilere og holde dem aktive i debug mål. Som kildekontroll, dette er en teknikk som har reddet meg i ræva oftere enn det har forårsaket meg sorg (den viktigste lakmustesten på enhver utvikling teknikk).

Svarte 13/10/2008 kl. 22:40
kilden bruker

stemmer
0

Hvis du skriver en offentlig API, gjør den som ringer til fordel for å hjelpe dem med å finne sine feil raskt, og se etter gyldige innganger.

Hvis du skriver en API der den som ringer kanskje ikke klarert (eller den som ringer til den som ringer), sjekket for gyldige innganger, fordi det er god sikkerhet.

Hvis APIer dine er bare tilgjengelig med troverdige innringere, som "interne" i C #, så ikke føler at du trenger å skrive alt det ekstra kode. Det vil ikke være nyttig for alle.

Svarte 13/10/2008 kl. 22:41
kilden bruker

stemmer
1

Du bør sjekke alle argumenter mot det sett av forutsetninger som du gjør i den funksjonen om sine verdier.

Som i ditt eksempel, hvis en null argument til funksjonen ikke gir noen mening, og du antar at alle som bruker din funksjon vil vite dette så blir vedtatt en null argument viser noen form for feil og en slags tiltak (f.eks . kaster et unntak). Og hvis du bruker hevder (som James Fassett fikk inn og sagt før meg ;-)) de koster deg ingenting i et versjonen. (De koster deg nesten ingenting i en debug-versjon heller)

Det samme gjelder enhver annen forutsetning.

Og det kommer til å være lettere å spore feil hvis du genererer det enn hvis du lar det til en viss standard bibliotek rutine å kaste unntaket. Du vil være i stand til å gi mye mer nyttig kontekstuell informasjon.

Det er utenfor grensene for dette spørsmålet, men du trenger ikke å eksponere de forutsetninger som din funksjon gjør - for eksempel gjennom kommentaren header til funksjonen.

Svarte 13/10/2008 kl. 22:42
kilden bruker

stemmer
1

Ifølge The Pragmatic Programmer av Andrew Hunt og David Thomas, er det ansvaret til den som ringer å sørge for at det gir gyldig inngang. Så må du nå velge om du vurderer en null-inngang for å være gyldig. Med mindre det er bestemt fornuftig å vurdere null til å være en gyldig inngang (f.eks er det sannsynligvis en god idé å vurdere null til å bli en juridisk innspill hvis du tester for likestilling), ville jeg vurdere det ugyldig. På den måten programmet, når den treffer feil inngang, vil mislykkes før. Hvis programmet kommer til å støte på en feil, vil du at det skal skje så snart som mulig. I tilfelle din Funksjonen virker utilsiktet får gått en null, bør du vurdere det å være en feil, og reagerer deretter (dvs. i stedet for å kaste et unntak, bør du vurdere å gjøre bruk av en påstand som dreper programmet, før du slipper program).

Klassisk design av kontrakten: Hvis inngangen er riktig, vil produksjonen være rett. Hvis inngangen er feil, det er en bug. (Hvis inngangen er rett, men produksjonen er galt, det er en feil. Det er en gimme.)

Svarte 14/10/2008 kl. 00:15
kilden bruker

stemmer
1

Jeg vil legge til et par presiseringer ( i fet skrift ) til god design ved kontrakt råd offerred av Brian tidligere ...

De priniples av "design av kontrakt" krever at du definerer hva som er akseptabelt for den som ringer å passere i (gyldig domeneinngangsverdier) og deretter, for noen gyldig innspill, hva metoden / leverandør vil gjøre.

For en intern metode, kan man definere NULL som utenfor området gyldige inngangsparametere. I dette tilfellet ville du umiddelbart hevde at inngangsparameterverdien ikke er null. Nøkkelen innsikt i denne kontrakten spesifikasjonen er at enhver samtale passerer en NULL-verdi ER en anroper BUG og feilen kastet av hevde påstanden er riktig atferd.

Nå, mens svært godt definert og parsimonius, hvis du utsette metoden til eksterne / offentlige innringere, bør du spørre deg selv, er at kontrakten jeg / vi egentlig vil? Sannsynligvis ikke. I et felles grensesnitt, vil du sannsynligvis godta NULL (som teknisk sett i domenet av inngangene at metoden godtar), men deretter avslå å behandle grasiøst w / en returmelding. (Mer arbeid for å møte den naturligvis mer komplekse kunderettede krav.)

I begge tilfeller det du leter etter er en protokoll som håndterer alle saker fra både perspektivet til den som ringer og leverandøren, ikke mange scattershot tester som kan gjøre det vanskelig å vurdere fullstendighet eller manglende fullstendighet i kontrakts tilstand dekning.

Svarte 14/10/2008 kl. 02:31
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more