簡體   English   中英

允許方法只取數字嗎?

[英]Allowing a method to take only numbers?

更新:我如何制作一個具有兩個參數的方法來接受任何原始數字類型,例如intuintfloatdouble等等( bool除外)?

我當前正在使用object ,但這意味着該方法可以接受任何類型。

public int[] MyNumberMethod(object a, object b)
{
    if (a is int || a is uint || a is short || a is ushort || a is long || a is ulong || a is byte || a is sbyte || a is float || a is double || a is decimal)
    {
        if (b is int || b is uint || b is short || b is ushort || b is long || b is ulong || b is byte || b is sbyte || b is float || b is double || b is decimal)
            return new int[] { Convert.ToInt32(b), Convert.ToInt32(a) };
    }

    return new int[] { 0, 0 };
}

那么既然您要使用除bool之外的所有基本類型,那該怎么辦?

public int MyNumberMethod<T>(T number) where T : struct
{
    if (!(number is bool) && number.GetType().IsPrimitive) 
        return Convert.ToInt32(number);

    return 0;
}

例如

MyNumberMethod<short>(5);

所有數字類型(double和float除外)都可以隱式轉換為十進制,float可以隱式轉換為double。 因此,如果您像這樣進行重載:

Method(double, double)
Method(decimal, double)
Method(decimal,decimal)
Method(double, decimal)

您的方法可以用任意兩個數字調用,但只能用任意兩個數字調用。

這可能不像其他答案那樣好,但是另一種選擇是創建您自己的結構,其中僅允許某些數據類型的值:

public struct Number
{
    #region Static methods and fields
        private static readonly Type[] allowedTypes = new Type[] { 
            typeof(int), typeof(uint), typeof(short), typeof(ushort),
            typeof(long), typeof(ulong), typeof(byte), typeof(sbyte),
            typeof(float), typeof(double), typeof(decimal)
        };

        private static void CheckIsNumber(dynamic val) {
            if (Array.IndexOf(allowedTypes, val.GetType()) == -1) { throw new InvalidCastException("Input type must be a number."); }
        }
    #endregion

    #region Constructor
        public Number(dynamic Value) {
            Number.CheckIsNumber(Value);
            _value = Value;
        }
    #endregion

    #region Properties
        private dynamic _value;
        public dynamic Value {
            get { return _value; }
            set {
                Number.CheckIsNumber(value);
                _value = value;
            }
        }
    #endregion

    #region Overridden methods
        public override bool Equals(object obj) { return _value.Equals(obj); }
        public override int GetHashCode()       { return _value.GetHashCode(); }
        public override string ToString()       { return _value.ToString(); }
    #endregion

    #region Conversion operators - Number
        public static implicit operator Number(uint val)    { return new Number(val); }
        public static implicit operator Number(short val)   { return new Number(val); }
        public static implicit operator Number(ushort val)  { return new Number(val); }
        public static implicit operator Number(long val)    { return new Number(val); }
        public static implicit operator Number(ulong val)   { return new Number(val); }
        public static implicit operator Number(byte val)    { return new Number(val); }
        public static implicit operator Number(float val)   { return new Number(val); }
        public static implicit operator Number(double val)  { return new Number(val); }
        public static implicit operator Number(decimal val) { return new Number(val); }
    #endregion

    #region Conversion operators - Misc. data types
        public static implicit operator int(Number num)     { return (int)num.Value; }
        public static implicit operator uint(Number num)    { return (uint)num.Value; }
        public static implicit operator short(Number num)   { return (short)num.Value; }
        public static implicit operator ushort(Number num)  { return (ushort)num.Value; }
        public static implicit operator long(Number num)    { return (long)num.Value; }
        public static implicit operator ulong(Number num)   { return (ulong)num.Value; }
        public static implicit operator byte(Number num)    { return (byte)num.Value; }
        public static implicit operator sbyte(Number num)   { return (sbyte)num.Value; }
        public static implicit operator float(Number num)   { return (float)num.Value; }
        public static implicit operator double(Number num)  { return (double)num.Value; }
        public static implicit operator decimal(Number num) { return (decimal)num.Value; }
    #endregion
}

每次更改值或創建結構的新實例時,它將驗證輸入值的數據類型是否與allowedTypes數組中的任何項目匹配。 如果沒有,它將拋出InvalidCastException

我還添加了轉換運算符,使您可以將其用作普通數,因此可以像使用其他任何數值數據類型一樣使用它:

Number myNum = 3.5;
myNum += 10.4;
double something = myNum - 6.0;

但是請記住,在使用doublefloat等時,必須添加小數點,否則它將假定數字是整數:

Number myNum = 3.5;
myNum -= 2;
MessageBox.Show(myNum.ToString()); //Shows "1" as the second line converts 'myNum' into an integer.

這么說,這就是您將其用於方法的方式:

public int[] MyNumberMethod(Number a, Number b)
{
    try {
        return new int[] { Convert.ToInt32(b), Convert.ToInt32(a) };
    }
    catch(InvalidCastException) {
        return new int[] { 0, 0 };
    }
}

並且由於有了轉換運算符,您無需指定(Number)轉換。 例如:

byte myByte = 133;

//Unnecessary.
MyNumberMethod((Number)17.4, (Number)myByte);

//This works just as fine.
MyNumberMethod(17.4, myByte);

首先,您必須調用GenericNumberMethod之類的其他函數,該函數將包含對MyNumberMethod的調用。 對於每種數據類型,必須具有帶有相應參數的GenericNumberMethod的實現。

public int MyNumberMethod(object number) {
    return Convert.ToInt32(number);
}

public int GenericNumberMethod(int number) {
    return MyNumberMethod(number);
}

public int GenericNumberMethod(decimal number) {
    return MyNumberMethod(number);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM