#c#
#c#
Вопрос:
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
var fP18VaR = (float) (int)e.Values[0];
}
Я получаю
Приведение, указанное в InvalidCastException, недопустимо
Почему это не работает?
Значение e.Values[0] равно: 6 666,00
Комментарии:
1.Что такое
e.Values[0]
, aHorse
? Редактировать Так оно и есть6 666,00
, десятичное / двойное число или astring
?2. Может быть, приведение к
int
уже завершается неудачей?3. например, значения [0]. GetType()?
4. Я согласен с @UweKeim .. Я думаю, что значения связаны с каким-то другим типом данных.
5. действительно ли это 6 [пробел] 666,00 ? Если это так, анализ int, вероятно, уже завершается с ошибкой
Ответ №1:
Проблема, с которой вы сталкиваетесь здесь, заключается в том, что оператор приведения C # означает разные вещи в разных ситуациях.
Возьмите этот пример, который вы привели:
object num = 10;
float fnum = (float)num;
Компилятор C # подумает, что вы говорите ему следующее: «Переменная num ссылается на значение с плавающей запятой в штучной упаковке; пожалуйста, распакуйте его и верните значение в штучной упаковке».
Вы получаете сообщение об ошибке, потому что это не штучный float, а штучный int .
Проблема в том, что C # использует идентичный синтаксис для двух совершенно не связанных операций: ‘unbox’ и ‘числовое преобразование’. Вот пример того, где приведение означает числовое преобразование:
int num = 10;
float fnum = (float)num;
Почти точно такой же код, и все же это не выдаст вам ошибку. И это потому, что компилятор C # обрабатывает это совершенно по-другому — этот код означает: «Пожалуйста, выполните числовое преобразование, преобразуя целое число, хранящееся в ‘num’, в значение с плавающей запятой одинарной точности».
Как вы узнаете, какую из этих двух совершенно не связанных операций он выберет? Все дело в типах источника и назначения. Если вы преобразуете из ‘object’ в тип значения, это всегда будет рассматриваться как unbox . Если вы преобразуете из одного числового типа в другой, это всегда будет рассматриваться как числовое преобразование.
Итак, как вы получаете желаемый результат? Ну, вам нужно выполнить обе операции: вам нужно распаковать int, а затем преобразовать его в значение с плавающей точкой. Итак, вам действительно нужно два приведения:
object num = 10;
float fnum = (float) (int)num;
Ужасно, да?
Самый простой способ сделать то, что вы хотите здесь, — полностью избежать приведения. Просто сделайте это:
float fnum = Convert.ToSingle(num);
Это принудит тип к одинарной точности с плавающей точкой, если это возможно.
Ответ №2:
Тип времени компиляции e.Values[0]
is Object
. Итак, вам действительно нужно выполнить приведение и / или преобразование, чтобы получить float
. Если
(int)e.Values[0]
завершается успешно, затем
(float) (int)e.Values[0]
добьется успеха. Следовательно, e.Values[0]
не может быть преобразован в int
.
Ваш следующий шаг — определить, что такое тип и значение среды выполнения e.Values[0]
, и попытаться понять, как преобразовать это в числовое значение.
Ответ №3:
Ваше приведение недопустимо, потому что e.Values[0] возвращает значение в штучной упаковке как объект, который сначала необходимо привести к исправлению базового типа. Чтобы преобразовать базовое значение в значение с плавающей запятой, сначала необходимо указать правильный тип.
Кроме того, если object — это не тип значения, а какой-то другой контейнер или, например, string — вам нужно сначала привести к этому контейнеру, а затем найти способ преобразовать это в float .
У Эрика Липпера есть отличная статья на эту тему: Представление и идентификация.
Ответ №4:
Рассмотрите возможность использования TryParse
вместо этого; немного подробный пример ниже, чтобы дать вам представление о том, как обрабатывать синтаксический анализ ошибок и как впоследствии преобразовать нулевое значение с плавающей точкой в обычное:
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
float? temp;
if (!float.TryParse(e.Values[0], out temp))
{
//code to handle problems parsing here
throw new InvalidCastException("Invalid cast: '{0}' cannot be parsed to a float", e.Values[0]);
}
//if we reach here (we've not thrown an error above), `temp` is not null
var fP18VaR = temp.Value;
}
ПРИМЕЧАНИЕ: эта функция учитывает текущую культуру; поэтому, если вы работаете с мультикультурными данными, вам нужно знать, в каком формате находятся цифры. Видишь http://msdn.microsoft.com/en-us/library/3s27fasw (v = против 110).aspx для получения дополнительной информации.