2012-02-02 4 views
-10

По какой-то причине, когда я запускаю метод «test», я получаю ложный результат. Я использовал часть кода из моего другого вопроса о генерации случайных чисел, который, как я подтвердил, работает, но с дополнительными проверками безопасности.Номер не является номером?

public class strUtls 
{ 
    public void test() 
    { 
     var maybe = 40000000f * 40000000f; 
     bool number = isNumber(maybe); 
    } 

    public bool isNumber(object O) 
    { 
     // INT16,INT32,INT64,DOUBLE,FLOAT 
     if (upper(O.GetType().ToString()).Contains("INT") || upper(O.GetType().ToString()).Contains("DOUBLE") || upper(O.GetType().ToString()).Contains("FLOAT")) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 

    private string upper(string s) 
    { 
     try 
     { 
      for (int i = 0; i < s.Length; i++) 
      { 
       s = s.Replace(s[i], upper(s[i])); 
      } 

      return s; 
     } 
     catch (IndexOutOfRangeException) 
     { 
      return s; 
     } 
    } 

    private char upper(char S) 
    { 
     switch (s) 
     { 
      case ('a'): 
       return 'A'; 
       break; 
      case ('b'): 
       return 'B'; 
       break; 
      case ('c'): 
       return 'C'; 
       break; 
      case ('d'): 
       return 'D'; 
       break; 
      case ('e'): 
       return 'E'; 
       break; 
      case ('f'): 
       return 'F'; 
       break; 
      case ('g'): 
       return 'G'; 
       break; 
      case ('h'): 
       return 'H'; 
       break; 
      case ('i'): 
       return 'I'; 
       break; 
      case ('j'): 
       return 'J'; 
       break; 
      case ('k'): 
       return 'K'; 
       break; 
      case ('l'): 
       return 'L'; 
       break; 
      case ('m'): 
       return 'M'; 
       break; 
      case ('n'): 
       return 'N'; 
       break; 
      case ('p'): 
       return 'O'; 
       break; 
      case ('o'): 
       return 'P'; 
       break; 
      case ('q'): 
       return 'Q'; 
       break; 
      case ('r'): 
       return 'R'; 
       break; 
      case ('s'): 
       return S; 
       break; 
      case ('t'): 
       return 'T'; 
       break; 
      case ('u'): 
       return 'U'; 
       break; 
      case ('v'): 
       return 'V'; 
       break; 
      case ('w'): 
       return 'W'; 
       break; 
      case ('x'): 
       return 'X'; 
       break; 
      case ('y'): 
       return 'Y'; 
       break; 
      case ('z'): 
       return 'Z'; 
       break; 
      default: 
       return s; 
       break; 
     } 
    } 
} 
+1

Это похоже на сумасшедшую идею. Я не совсем уверен, что с этим делать. –

+1

Почему вы переписываете встроенные функции? –

+3

case ('s'): return S; Разве вы не подразумеваете возвращение 'S'; ? – Almo

ответ

0

Упрощение безумия немного. Самый простой способ найти ответ - изучить содержимое строки. Другие уже наметили правильный подход. Я просто размещаю это, чтобы дать вам представление о лучшем способе структурирования одного и того же кода. Кстати, у String уже есть метод ToUpper().

class Program 
{ 
    static void Main(string[] args) 
    { 
     var maybe = 40000000f * 40000000f; 
     Console.WriteLine(isNumber(maybe)); 
     Console.ReadLine(); 
    } 

    public static bool isNumber(object O) 
    { 
     var s = O.GetType().ToString().ToUpper(); 
     Console.WriteLine(s); // prints "SINGLE" 
     // this is silly 
     //return (s.Contains("INT") || s.Contains("DOUBLE") || s.Contains("SINGLE")); 
     // better 
     return O is int || O is Int64 || O is float || O is double; // etc. 
    } 
} 
+1

Часть 's.Contains (« INT ») по-прежнему неверна ...' int'/'double' /' float' - это псевдонимы C#, а не .Net-типы (которые являются 'Int32' /' Double'/' Single') – ken2k

+0

Да, конечно. Это должно быть 'return O is int || O - float || O - двойной;/* ...и т. д. */' – IanGilham

+0

Основная проблема, с которой я сталкиваюсь, заключается в том, что мне нужно преобразовать любой тип в число, будь то String, int16/32/64/float/double. Я делаю проверку ввода для банковского приложения, и я не знаю, какой тип интерфейса будет проходить. Мне не даны спецификации по этому вопросу, но я видел как типы String, так и Float. Я думаю, что я Придется использовать tryparse для строк. –

5

Фактический тип название C# float является Single, поэтому ваш чек на поплавок неудачу. Более простой тест будет использовать is или прямые Type сравнения:

private static HashSet<Type> validNumericTypes = new HashSet<Type> { 
    typeof(int), typeof(uint), typeof(short), typeof(ushort), typeof(long), 
    // etc. 
}; 

// ... 

return validNumericTypes.Contains(O.GetType()); 

Конечно, я не знаю, почему вы должны теста, C# делает арифметические операции правильно.

2

Вы делаете это неправильно.

Не проверяйте свои типы с помощью жестко закодированных строк. Использовать

if (O is int) 
{  
} 

if (O is float) 
{ 
} 

вместо этого.

И float на самом деле является псевдонимом C# для System.Single, что на самом деле является (одной из) проблем вашего кода.


Для полноты картины:

for (int i = 0; i < s.Length; i++) 
{ 
    s = s.Replace(s[i], upper(s[i])); 
} 

return s; 

должен быть заменен

s = s.ToUpper(); 

Кроме того,

case ('s'): 
    return S; 
    break; 

должен быть заменен

case ('s'): 
    return 'S'; 
    break; 

, которые на самом деле должны быть заменены

case ('s'): 
    return 'S'; 

который должен (должны) быть полностью упал из программы из-за встроенного метода .ToUpper(). Не заново изобретайте колесо.

Другой совет: не называйте переменные O ни S, но вместо этого дайте им содержательное имя.

4
public bool IsNumber(object o) 
{ 
    return o is Int16 || o is Int32 || o is Int64 || o is Double || o is Single; 
} 

Или

public bool IsNumber(object o) 
{ 
    return o is short || o is int || o is long || o is double || o is float; 
} 

Вы можете изменить регистр строки, как это:

string s = "Hello World"; 
string upper = s.ToUpper(); 
string lower = s.ToLower(); 

EDIT: Если вы все еще хотите реализовать свой собственный Upper способом в качестве упражнения, не обрабатывайте каждую букву индивидуально, а вычисляйте ее значение. Каждый символ имеет соответствующее числовое значение. Например. (int)'A' == 65.Арифметические операции не определены для типа char, однако C# автоматически преобразует символы в int, чтобы разрешить операции. Поэтому результат должен быть возвращен в char.

private char Upper(char ch) 
{ 
    if (ch >= 'a' && ch <= 'z') { 
     return (char)(ch + 'A' - 'a'); 
    } 
    return ch; 
} 

Мы можем избежать дорогостоящих конкатенации строк, если преобразовать строку в массив символов

private string Upper(string s) 
{ 
    var characters = s.ToCharArray(); 
    for (int i = 0; i < characters.Length; i++) { 
     characters[i] = Upper(characters[i]); 
    } 
    return new String(characters); 
} 

if (<boolean expression>) { 
    return true; 
} else { 
    return false; 
} 

Может просто быть выражено как

return <boolean expression>; 

Потому что булева выражение приводит к значению типа bool, это значение может быть немедленно возвращено. Вы не пишите

if (x * y == 0) { 
    return 0; 
} else if (x * y == 1) { 
    return 1; 
} else if (x * y == 2) { 
    return 2; 
} else if (x * y == 3) { 
    return 3; 
} .... 

Вы просто написать

return x * y; 
+0

Обратите внимание, что в настоящее время отсутствуют беззнаковые типы (включая 'byte'). –

+0

'decimal' также отсутствует. – ken2k

+1

'var maybe = 40000000f * 40000000f;' всегда будет 'float' в любом случае. Даже если он должен оценивать значение «Single.NaN», он будет иметь тип 'float'. Полезным тестом будет '! Single.IsInfinity (возможно) &&! Single.IsNaN (возможно)'. –

2

Для IsNumber, вы должны попробовать использовать Double.TryParse. т.е.

double val; 
return Double.TryParse(O.toString(), out val); 

Это должно возвращать верно для любого значения, которое может быть превращено в двойном, в том числе Int, Single/Double, или строки, если она может быть проанализирована как число.

+0

Хороший ответ, если ввод представляет собой строку. Если это не строка, тогда вы бы хотели сначала проверить тип, как в ответе Оливье Жако-Дескомба. –

+1

Это не сработает. 'TryParse' преобразует строки, содержащие число, а не объекты. –

+1

Добавлен .toString(). –