2010-03-10 37 views
13

Tôi muốn tạo một hàm kiểm tra nếu giá trị số được truyền dưới dạng đối số có giá trị lớn hơn không. Một cái gì đó như thế này:Làm thế nào tôi có thể so sánh bất kỳ loại số nào với số không trong C#

public bool IsGreaterThanZero(object value) 
{ 
    if(value is int) 
    { 
     return ((int)value > 0); 
    } 
    else if(value is float) 
    { 
     // Similar code for float 
    } 

    return false; 
} 

Tôi có thể cố gắng cast đối tượng thông qua như là đối số của hàm để một kiểu dữ liệu số vì vậy tôi sau đó có thể so sánh nó với zero chứ không phải là kiểm tra đối với từng loại nhập nếu tôi tuyên bố? Nếu dàn diễn viên thất bại, tôi sẽ trả về sai. Có cách nào tốt hơn (đọc ngắn hơn, dễ đọc hơn) để thực hiện việc này không?

Chỉnh sửa: Một số đã hỏi về nếu tôi biết loại sẽ là số, tại sao đối tượng, v.v ... tôi hy vọng điều này sẽ làm cho mọi thứ rõ ràng hơn.

Chức năng này sẽ là một phần của một chuyển đổi Silverlight mà thực hiện giao diện IValueConverter trong đó có một chữ ký chuyển đổi của

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 

A đầu tiên, tôi chỉ muốn chuyển đổi để làm việc với ints nhưng trí tưởng tượng của tôi bắt đầu chạy hoang dã và nghĩ xem nếu tôi có số điểm động và các loại số khác. Tôi muốn làm cho bộ chuyển đổi linh hoạt nhất có thể. Ban đầu tôi nghĩ rằng tất cả những thông tin bổ sung này sẽ cản trở những gì tôi muốn làm vì vậy tôi không đưa nó vào câu hỏi của mình.

+5

Tại sao là một lợi thế này để chỉ sử dụng > toán tử? – Nick

+0

những gì về đúc nó như là một chuỗi so sánh nó với "0" – Luiscencio

+0

@Nick bạn không thể so sánh một int với một đối tượng ... – Langdon

Trả lời

15

sở thích của tôi sẽ là:.

public bool IsGreaterThanZero(object value) 
{ 
    if(value is IConvertible) 
    { 
     return Convert.ToDouble(value) > 0.0; 
    } 

    return false; 
} 

này sẽ xử lý tất cả IConvertible loại một cách an toàn (bao gồm tất cả các dấu chấm động và các loại nguyên trong khuôn khổ, nhưng cũng có bất kỳ loại tùy chỉnh nào).

+0

Điều này sẽ không ném một ngoại lệ nếu người gọi được chuyển vào một giá trị chuỗi không phải là số không? –

+0

@Mike: Tiềm năng- Nó có thể được xử lý, nếu cần thiết, thông qua một try/catch, mặc dù. –

+0

@Mike: OP xác định rằng đây sẽ là một giá trị số, mặc dù - nếu đó là sự thật, ở trên là tốt. Nếu không, bạn cần xử lý ngoại lệ ... –

2

Hãy thử:

double tempValue; 
if(double.TryParse(value.ToString(), out tempValue) 
{ 
    return (tempValue > 0) 
} 
else 
{ 
    return false; 
} 
+0

Đây không phải là đặc biệt hiệu quả, vì nó sẽ chuỗi, sau đó để tăng gấp đôi ... –

+0

yeah, nhưng tôi con số thay thế khác là sử dụng Convert.ToDouble hoặc một cái gì đó như thế, mà (A) có thể ném một ngoại lệ và (B Tôi cũng không biết hiệu quả của nó. Nhưng dù sao, nó sẽ là lý tưởng nếu NET có một Covert.TryToDouble mà trả lại một boolean thay vì ném một ngoại lệ, nhưng điều đó dường như không tồn tại –

+0

@Mike: Xem câu trả lời của tôi - về cơ bản xử lý trường hợp đó, mà không có chuyển đổi chuỗi ... –

1

Tại sao không chỉ Convert.ToDouble hoặc Convert.ToDecimal và sau đó làm việc so sánh? Có vẻ như rằng sẽ xử lý hầu hết các loại mà ai đó có thể vượt qua trong

14

Trình gọi gọi có biết loại không? Nếu có, cách thực hiện:

public static bool GreaterThanZero<T>(T value) where T : struct, IComparable<T> 
{ 
    return value.CompareTo(default(T)) > 0; 
} 

Không cần chuyển đổi và phải hoạt động với bất kỳ loại giá trị được tích hợp nào và bất kỳ loại giá trị hợp lý nào bạn tự tạo ra. (Ví dụ, điều này sẽ tốt với cấu trúc Duration của Noda Time.)

Lưu ý rằng người gọi không phải biết loại trực tiếp - nó chỉ có thể biết nó như một tham số kiểu khác với cùng ràng buộc. Phải thừa nhận rằng điều này có thể không phù hợp với hoàn cảnh của bạn, nhưng tôi nghĩ tôi sẽ đề cập đến nó. Nếu không biết loại nào ở thời gian biên dịch (và bạn không ưa thích việc gõ động để thực hiện công việc cho bạn trong C# 4!) Thì gọi số Convert.ToDouble có lẽ là đặt cược tốt nhất của bạn - chỉ cần biết rằng nó có thể có vấn đề với System.Numerics.BigInteger từ .NET 4.0.

3

Bạn có thể tránh boxing và unboxing sử dụng Generics:

Đây là định nghĩa của một hàm

class GenericComparation { 
    public static bool IsGreaterThanZero<T>(T value) where T : IComparable<T> { 
     // Console.WriteLine(value.GetType().Name) 
     return value.CompareTo(default(T)) > 0; 
    } 
} 

Cách sử dụng:

Console.WriteLine(GenericComparation.IsGreaterThanZero(1)); 
Console.WriteLine(GenericComparation.IsGreaterThanZero(-1.1)); 
Console.WriteLine(GenericComparation.IsGreaterThanZero(Decimal.Zero)); 
4

Hả? Bạn quan tâm đến điều gì là số số?

public bool IsGreaterThanZero(double value) 
{ 
    return value > 0; 
} 

Những tất cả công việc ...

IsGreaterThanZero((int)2); 
    IsGreaterThanZero((long)2); 
    IsGreaterThanZero((double)2); 
    IsGreaterThanZero((float)2); 
    IsGreaterThanZero((byte)2); 
    IsGreaterThanZero((ulong)2); 
+1

Với tôi đây là câu trả lời hay nhất. Gõ an toàn (không có ngoại lệ đúc), hiệu quả (không chuyển đổi hoặc thử/bắt) và bao gồm tất cả các cơ sở. – Russell

+1

@Russel: Sẽ có các phôi tiềm ẩn trên trang web cuộc gọi cho mọi thứ nhưng gấp đôi. Kiểm tra nó với .Net Reflector. Nó cũng không hoạt động hoàn toàn cho thập phân. –

+0

+1 Hightechrider và +1 Russell: Tôi hoàn toàn đồng ý với cả hai bạn. –

1

này cách đơn giản nhất và nhanh nhất để so sánh bất kỳ loại số Để không được như sau:

public bool IsGreaterThanZero(object value) 
{ 
    if (value != null && value.GetType().IsValueType) 
     return System.Convert.ToDouble(value) > 0; 
    return false; 
} 
+0

IsValueType không đảm bảo rằng giá trị là số. Có thể là một cấu trúc hoặc chỉ đơn giản là "đối tượng", hoặc một chuỗi tùy ý. –

Các vấn đề liên quan