Helpex - Trao đổi & giúp đỡ Đăng nhập
78

Tôi muốn kiểm tra xem một đối tượng là một số do đó .ToString()sẽ cho kết quả trong một chuỗi có chứa chữ số và +, -,.

Có thể bằng cách kiểm tra loại đơn giản trong .net (như if (p is Number):)?

Hoặc tôi nên chuyển đổi thành chuỗi, sau đó thử phân tích cú pháp để tăng gấp đôi?

Cập nhật: Để làm rõ đối tượng của tôi là int, uint, float, double, v.v. nó không phải là một chuỗi. Tôi đang cố gắng tạo một hàm có thể tuần tự hóa bất kỳ đối tượng nào thành xml như thế này:

<string>content</string>

hoặc là

<numeric>123.3</numeric>

hoặc đưa ra một ngoại lệ.

78 hữu ích 3 bình luận 104k xem chia sẻ
10 trả lời 10
158

Bạn chỉ cần thực hiện kiểm tra loại cho từng loại số cơ bản.

Đây là một phương thức mở rộng nên thực hiện công việc:

public static bool IsNumber(this object value)
{
    return value is sbyte
            || value is byte
            || value is short
            || value is ushort
            || value is int
            || value is uint
            || value is long
            || value is ulong
            || value is float
            || value is double
            || value is decimal;
}

Điều này sẽ bao gồm tất cả các loại số.

Cập nhật

Có vẻ như bạn thực sự muốn phân tích số từ một chuỗi trong quá trình khử lưu huỳnh. Trong trường hợp này, nó có lẽ sẽ là tốt nhất để sử dụng double.TryParse.

string value = "123.3";
double num;
if (!double.TryParse(value, out num))
    throw new InvalidOperationException("Value is not a number.");

Tất nhiên, điều này sẽ không xử lý số nguyên rất lớn / số thập phân dài, nhưng nếu đó là trường hợp bạn chỉ cần thêm các cuộc gọi bổ sung vào long.TryParse/ decimal.TryParse/ bất cứ điều gì khác.

158 hữu ích 5 bình luận chia sẻ
34

Lấy từ Blog của Scott Hanselman :

public static bool IsNumeric(object expression)
{
    if (expression == null)
    return false;

    double number;
    return Double.TryParse( Convert.ToString( expression
                                            , CultureInfo.InvariantCulture)
                          , System.Globalization.NumberStyles.Any
                          , NumberFormatInfo.InvariantInfo
                          , out number);
}
34 hữu ích 1 bình luận chia sẻ
18

Tận dụng thuộc tính IsPrimitive để tạo phương thức tiện ích mở rộng tiện dụng:

public static bool IsNumber(this object obj)
{
    if (Equals(obj, null))
    {
        return false;
    }

    Type objType = obj.GetType();
    objType = Nullable.GetUnderlyingType(objType) ?? objType;

    if (objType.IsPrimitive)
    {
        return objType != typeof(bool) && 
            objType != typeof(char) && 
            objType != typeof(IntPtr) && 
            objType != typeof(UIntPtr);
    }

    return objType == typeof(decimal);
}

EDIT: Đã sửa theo ý kiến. Các tổng quát đã bị xóa do các loại giá trị hộp .GetType (). Cũng bao gồm sửa chữa cho các giá trị nullable.

18 hữu ích 5 bình luận chia sẻ
9

Có một số câu trả lời tuyệt vời ở trên. Đây là một giải pháp tất cả trong một. Ba quá tải cho các trường hợp khác nhau.

// Extension method, call for any object, eg "if (x.IsNumeric())..."
public static bool IsNumeric(this object x) { return (x==null ? false : IsNumeric(x.GetType())); }

// Method where you know the type of the object
public static bool IsNumeric(Type type) { return IsNumeric(type, Type.GetTypeCode(type)); }

// Method where you know the type and the type code of the object
public static bool IsNumeric(Type type, TypeCode typeCode) { return (typeCode == TypeCode.Decimal || (type.IsPrimitive && typeCode != TypeCode.Object && typeCode != TypeCode.Boolean && typeCode != TypeCode.Char)); }
9 hữu ích 5 bình luận chia sẻ
7

Thay vì tự lăn, cách đáng tin cậy nhất để biết loại đang xây dựng có phải là số có lẽ là để tham khảo Microsoft.VisualBasicvà gọi Information.IsNumeric(object value). Việc triển khai xử lý một số trường hợp tinh tế như char[]và chuỗi HEX và OCT.

7 hữu ích 2 bình luận chia sẻ
4

Có ba khái niệm khác nhau ở đó:

  • để kiểm tra xem đó có phải một số (tức là một giá trị số (thường được đóng hộp) không), hãy kiểm tra loại với is- ví dụif(obj is int) {...}
  • để kiểm tra xem một chuỗi có thể được phân tích cú pháp dưới dạng số hay không; sử dụngTryParse()
  • nhưng nếu đối tượng không phải là một số hoặc một chuỗi, nhưng bạn nghi ngờ ToString()có thể đưa ra một cái gì đó trông giống như một số, sau đó gọi ToString() và coi nó như một chuỗi

Trong cả hai trường hợp đầu tiên, có thể bạn sẽ phải xử lý riêng từng loại số bạn muốn hỗ trợ ( double/ decimal/ int) - ví dụ, mỗi loại có phạm vi và độ chính xác khác nhau.

Bạn cũng có thể nhìn vào regex để kiểm tra sơ bộ nhanh chóng.

4 hữu ích 0 bình luận chia sẻ
3

Giả sử đầu vào của bạn là một chuỗi ...

Có 2 cách:

sử dụng Double.TryPude ()

double temp;
bool isNumber = Double.TryParse(input, out temp);

sử dụng Regex

 bool isNumber = Regex.IsMatch(input,@"-?\d+(\.\d+)?");
3 hữu ích 0 bình luận chia sẻ
2

Bạn có thể sử dụng mã như thế này:

if (n is IConvertible)
  return ((IConvertible) n).ToDouble(CultureInfo.CurrentCulture);
else
  // Cannot be converted.

Nếu đối tượng của bạn là một Int32, Single, Doublevv nó sẽ thực hiện việc chuyển đổi. Ngoài ra, một chuỗi thực hiện IConvertiblenhưng nếu chuỗi không thể chuyển đổi thành gấp đôi thì một chuỗi FormatExceptionsẽ bị ném.

2 hữu ích 2 bình luận chia sẻ
1

Vâng, điều này hoạt động:

object x = 1;
Assert.That(x is int);

Đối với số dấu phẩy động, bạn sẽ phải kiểm tra bằng cách sử dụng loại float:

object x = 1f;
Assert.That(x is float);
1 hữu ích 4 bình luận chia sẻ
1

Nếu yêu cầu của bạn thực sự

.ToString () sẽ dẫn đến một chuỗi chứa các chữ số và +, - ,.

và bạn muốn sử dụng double.TryPude sau đó bạn cần sử dụng quá tải có tham số NumberStyles và đảm bảo rằng bạn đang sử dụng văn hóa bất biến.

Ví dụ: đối với một số có thể có dấu đầu, không có khoảng trắng ở đầu hoặc cuối, không có dấu phân cách hàng nghìn và dấu phân cách thập phân theo chu kỳ, hãy sử dụng:

NumberStyles style = 
   NumberStyles.AllowLeadingSign | 
   NumberStyles.AllowDecimalPoint | 
double.TryParse(input, style, CultureInfo.InvariantCulture, out result);
1 hữu ích 0 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ c# .net serialization xml-serialization , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading