У меня есть функция, которая, помимо прочего, принимает объект и тип и преобразует объект в этот тип. Однако входной объект часто является двойным, а тип - некоторым вариантом int (uint, long и т. д.). Я хочу, чтобы это работало, если круглое число передается как двойное (например, 4.0), но чтобы генерировать исключение, если десятичное число передается в (4.3). Есть ли более элегантный способ проверить, является ли тип каким-то int?
if (inObject is double && (targetType == typeof (int)
|| targetType == typeof (uint)
|| targetType == typeof (long)
|| targetType == typeof (ulong)
|| targetType == typeof (short)
|| targetType == typeof (ushort)))
{
double input = (double) inObject;
if (Math.Truncate(input) != input)
throw new ArgumentException("Input was not an integer.");
}
Спасибо.
Также похоже, что вы дублируете функциональность в System.Convert ...
Хорошие моменты, Джон, я обязательно запомню поплавки. Дэйв, когда вы меняете System.Convert.ChangeType с double на int, он молча выполняет банковское округление. Этот код предназначен для предотвращения этого до того, как будет выполнен вызов System.Convert.





Кажется, это делает то, о чем вы просите. Я тестировал его только на двойные, плавающие и целые числа.
public int GetInt(IConvertible x)
{
int y = Convert.ToInt32(x);
if (Convert.ToDouble(x) != Convert.ToDouble(y))
throw new ArgumentException("Input was not an integer");
return y;
}
Я бы подумал, что у вас должна быть возможность использовать комбинацию Convert.ToDecimal и x% y, где y = 1 и проверка результата == 0;
Думаю, вы обнаружите, что это неправда ...? 2.4% 1 0.39999999999999991
int intvalue;
if (!Int32.TryParse(inObject.ToString(), out intvalue))
throw InvalidArgumentException("Not rounded number or invalid int...etc");
return intvalue; //this now contains your value as an integer!
Пара замечаний - 1) не забывайте поплавки. 2) Возможно, вы захотите использовать Math.Round (), потому что иногда 1.000000001 появляется вместо 1.0 из-за проблем с плавающей запятой.