Vorrei tentare di analizzare, se non riesce, quindi tentare di analizzare un valore di capacità superiore. Se il valore di capacità più elevato supera l'analisi, allora sai che è fuori portata. Se fallisce, allora è un input negativo.
string outOfRange = "2147483648"; // +1 over int.MaxValue
int result;
if (!Int32.TryParse(outOfRange, out result))
{
long rangeChecker;
if (Int64.TryParse(outOfRange, out rangeChecker))
//out of range
else
//bad format
}
Purtroppo, non credo che ci sia un modo per fare questo genericamente per qualsiasi tipo; dovresti scrivere un'implementazione per tutti i tipi. Quindi, ad esempio, che cosa fare per Int64
? Forse utilizzare BigInteger
invece:
string outOfRange = "9223372036854775808"; // +1 over Int64.MaxValue
long result;
if (!Int64.TryParse(outOfRange, out result))
{
BigInteger rangeChecker;
if (BigInteger.TryParse(outOfRange, out rangeChecker))
//out of range
else
//bad format
}
EDIT: double
valori in virgola mobile possono essere più divertente dal momento che per quanto ne so, non c'è "BigDecimal" e si possono rendere conto anche per i valori che si avvicinano 0 per lo estremo (non sicuro a tale proposito). Forse potresti eseguire una variazione sul controllo BigInteger
ma potresti anche dover tenere conto dei punti decimali (probabilmente una semplice espressione regolare sarebbe la migliore qui per avere solo numeri, un segno negativo facoltativo e solo al massimo punto decimale).Se ci sono punti decimali, dovresti troncarli e controllare semplicemente la parte intera della stringa.
EDITx2: Ecco un piuttosto brutto implementazione per il controllo double
valori troppo:
// +bajillion over Double.MaxValue
string outOfRange = "90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.1";
double result;
if (!Double.TryParse(outOfRange, out result))
{
string bigIntegerInput = outOfRange;
if (!Regex.IsMatch(bigIntegerInput, @"^-?[0-9]\d*(\.\d+)?$"))
//bad format
int decimalIndex = bigIntegerInput.IndexOf('.');
if (decimalIndex > -1)
bigIntegerInput = bigIntegerInput.Substring(0, decimalIndex);
BigInteger rangeChecker;
if (BigInteger.TryParse(bigIntegerInput, out rangeChecker))
//out of range
else
//bad format
}
Ma onestamente, a questo punto, penso che abbiamo appena andati fuori di testa. A meno che non avere qualche vero e proprio collo di bottiglia, o l'applicazione dispone di out-of-range valori immessi spesso, si potrebbe essere meglio solo la cattura di loro il tempo dispari succede come in this answer o forse più semplicemente, l'applicazione di un regex a l'input. Nel mio ultimo esempio, potrei anche aver appena smesso dopo aver fatto la regex lo stesso (ma non lo so in cima alla mia testa se le implementazioni TryParse
sono più clemente, consentendo la notazione esponenziale/scientifica. dovrebbe coprire anche questi)
è l'analisi su un valore maggiore capacità primo (detto 'long', o' uint' se si sa avere solo positivi) quindi controllare 'Int32.Max/MinValue' percorribile? –
Suppongo che potrebbe essere una soluzione. Forse qualcosa di più generico che potrebbe funzionare con qualsiasi tipo di contenitore. – gleng
Perché non usi sempre la maggiore capacità necessaria se è possibile che il tuo valore trabocchi capacità più piccole? Puoi aggiungere dettagli sul contesto? –