Переключение регистра и проверки дженериков - PullRequest
10 голосов
/ 21 марта 2012

Я хочу написать функцию, которая по-разному форматирует int и decimal в строку

У меня есть этот код:

и я хочу переписать его в дженерики:

    public static string FormatAsIntWithCommaSeperator(int value)
    {
        if (value == 0 || (value > -1 && value < 1))
            return "0";
        return String.Format("{0:#,###,###}", value);
    }

    public static string FormatAsDecimalWithCommaSeperator(decimal value)
    {
        return String.Format("{0:#,###,###.##}", value);
    }


    public static string FormatWithCommaSeperator<T>(T value) where T : struct
    {
        string formattedString = string.Empty;

        if (typeof(T) == typeof(int))
        {
            if ((int)value == 0 || (value > -1 && value < 1))
            return "0";

            formattedString = String.Format("{0:#,###,###}", value);
        }

        //some code...
    }

    /// <summary>
    /// If the number is an int - returned format is without decimal digits
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static string FormatNumberTwoDecimalDigitOrInt(decimal value)
    {
        return (value == (int)value) ? FormatAsIntWithCommaSeperator(Convert.ToInt32(value)) : FormatAsDecimalWithCommaSeperator(value);
    }

Как я могу использовать T в теле функции?

Какой синтаксис я должен использовать?

Ответы [ 6 ]

34 голосов
/ 21 марта 2012

Вы можете использовать TypeCode для переключения:

switch (Type.GetTypeCode(typeof(T)))
{
    case TypeCode.Int32:
       break;
    case TypeCode.Decimal:
       break;
}
7 голосов
/ 26 апреля 2018

В современном C #:

public static string FormatWithCommaSeperator<T>(T value) where T : struct
{
    switch (value)
    {
        case int i:
            return $"integer {i}";
        case double d:
            return $"double {d}";
    }
}
4 голосов
/ 21 марта 2012

Редактировать: Если вы хотите обрабатывать только int и double, просто перегрузите две:

DoFormat(int value)
{
}

DoFormat(double value)
{
}

Если вы настаиваете на использовании дженериков:

switch (value.GetType().Name)
{
    case "Int32":
        break;
    case "Double":
        break;
    default:
        break;
}

OR

if (value is int)
{
    int iValue = (int)(object)value;
}
else if (value is double)
{
    double dValue = (double)(object)value;
}
else
{
}
1 голос
/ 21 марта 2012

Вы можете вместо использования дженериков использовать IConvertible

    public static string FormatWithCommaSeperator(IConvertible value)
    {
            IConvertible convertable = value as IConvertible;
            if(value is int)
            {
                int iValue = convertable.ToInt32(null);
                //Return with format.
            }
            .....
    }
0 голосов
/ 21 марта 2012

Вы можете проверить тип переменной;

    public static string FormatWithCommaSeperator<T>(T value)
    {
        if (value is int)
        {
            // Do your int formatting here
        }
        else if (value is decimal)
        {
            // Do your decimal formatting here
        }
        return "Parameter 'value' is not an integer or decimal"; // Or throw an exception of some kind?
    }
0 голосов
/ 21 марта 2012

В качестве альтернативы вы всегда можете сделать:

public static string FormatWithCommaSeparator<T>(T[] items)
{
    var itemArray = items.Select(i => i.ToString());

    return string.Join(", ", itemArray);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...