Как стать автором
Обновить

Комментарии 76

aaa, очевидно, проверку не пройдёт, поскольку ссылки фиг совпадут, потом на Parse вылетит ошибка
bbb — всё нормально, на PageB
почему на Parse вылетит ошибка?
Потому что «aaa» не шибко-то похоже на int в десятичной системе. Нужно юзать перегруженный Parse с заданным NumberStyles, если хочется сравнивать с 0xAAA, либо TryParse, если «aaa» — всё же строка.
а вообще, есть тоже один нюанс. Если зайти на страницу тестовую, то вылетит на parse ошибка, это да, потому что в querystring будет пусто. Соответственно перекинет на Error.aspx
ссылки идут с другой страницы (например, с Default.aspx)
ID указан в том виде, что я описал
В querystring возможно, но Request[«ID»] также ищет и в куках, форме и серверных переменных.
сначала ищет в кверистринг, так что тут все нормально
а, я Вас понял :) извиняюсь
к сожалению, ответ неправильный
А как же интернирование строк? :)
C «4» всё понятно, && не пускает до ошибочного кода, и редирект на дефолт.
10 — int занимает в памяти меньше, чем long, и привести не получается (вроде так).
тоже неверно.
пришлось апдейт написать для минусующих, а то уже вылетел из захабреных (
Не переживайте, это не я.
и на том спасибо
Пошли вопросы аля «Я тут написал хрен знает сколько строк кода, а вы без компилятора попробуйте определить, что выведет программа и где именно я спрятал подводный камень». Это уже не интересно. Если задаёте вопросы, то задавайте их по существу.
подводный камень там настолько большой, что я попытался его прикрыть веточками…
пока что хабраюзеры видят только эти веточки
кстати, компилятором пользоваться я не запрещал
я, может, совсем чепуху скажу, не пинайте меня, ибо C# я знаю не так глубоко.

Я сейчас попытаюсь объяснить, почему нельзя распаковать boxedI. Когда упаковываем int, создаётся объект, под него выделяется память, нужная для зранения int, когда же мы распаковываем в long без создания переменной, то у нас не хватает памяти, поэтому выпадает эксепшн. Прошу гуру C# не сильно смеяться, если чепуху сказал :)
дело не в нехватке памяти, наоборот, long длинее чем int. память для временного long выделяется на стеке или в регистре, так что с памятью все в порядке.
ошибка возникает просто из-за несоответствия типов — боксированная переменная содержит ссылку на объект-тип int, а не long, поэтому приведение не срабатывает
не знаю, у одного у меня так, или это и есть камень, внутри блока try catch не работают редиректы. Чтобы это исправить, можно отказаться от трайкеч, при парсинге использовать tryparse, при сравнении с aaa использовать просто строки (да и вообще можно везде поставить switch). Если не нашли пути, то переходим на error.aspx
отказаться от try/catch не всегда возможно, хорошо если есть аналог Parse-TryParse. а если нет?
а нет только во фреймворке 1.1 и ниже. В другом случае, можно позаимствовать идею из этих методов. Благо, .net reflector существует :)
я имею в виду, если приходится вызывать не int.Parse(), а MyClass.GetValue(), у которого нет аналога с Try…
Исправляеться вот так:
long b = Convert.ToInt64(box);

вот так:
long b = (long)(int)box; //не желательно, т.к. мы точно не знаем, что там long/int? итд.

if (object.ReferenceEquals(Request[«ID»], «aaa»)) //true, if ID=«aaa» т.е. сравнение для строк проходит иначе чем для всех остальных объектов.

Просто пример:
var a = «aaa»
object.ReferenceEquals(a, «aaa»); //true
но
a += «a»;
object.ReferenceEquals(a, «aaa»); //false
причина:
у строк оператор += перегружен и он создаст новый экземпляр.

к тому же .NET строки ещё и кэширует.

Ответ:
~/PageA.aspx (присание выше)
~/PageB.aspx //всё ок, если не вдаваться в подробности культурологии и прочего
~/Error.aspx //Invalid Cast Exception
~/Error.aspx //Invalid Cast Exception

описание*
решение проблемы более-менее годится, но вы решаете не ту проблему
ответ на вопрос «на тройку» неправильный
Всегда будет перехдить по Response.Redirect("~/Error.aspx"); Т.к. какой то из методов всегда генерирует исключение. Которое перехватывает наш try{}catch{}
Не так давно в каком то тематическом блоге данная ситуация разбиралась.
да, ответ на тройку правильный )
false поставьте в Response.Redirect("...", false). Проблема эта часто описывалась.

Вообще мне честно говоря, эти этюды кажется не очень полезными сообществу — сам заглядываю, но не голосую.
видимо, не так часто, поскольку на хабре я не нашел нужного топика, и как видите, пока еще никто не ответил, почему так
а Ваше предложение тоже не очень устраивает, потому что тогда будут возникать события контролов типа OnChange и т.д. Я же когда пишу Redirect, хочу этого избежать
Не в тех кругах общаетесь. :) Попробуйте зайти на GotDotNet и найти там проблему эту.
это такой тонкий пиар? )
решение проблемы можно найти где угодно, но главное — понять принцип, почему данный код работает именно так
а решение с false все еще не устраивает )
:) а я и не собираюсь делать, чтобы кого-то что-то устраивало. Пиарить GotDotNet, думаю, не нужно, про него и так все хорошо знают. Вот еще советы:
Если хотите продолжать, делайте топик хотя бы закрытый. Как думаете, если тут php-разработчики сидят, они хотят видеть такие «этюды» каждый день? А если по каждому языку такой «этюд»?
Для меня таких «этюдов» море на GotDotNet, я лучше потрачу свои силы, чтобы действительно народу помочь, а не поломать мозг в соревновании у кого длиннее ;)
кстати, насчет полезности…
что было бы полезнее, на Ваш взгляд?
Не знаю. Может и это полезно. Например, этот «этюд» и меня заинтересовал.
В любом случае — делайте их по крайней мере внутри .net блога. Так тут будут только заинтересованные.
*в растерянности*
а я где сделал?
имел ввиду закрытый, о чем написал тут
понял, спасибо
простите новичка )
а эти закрытые топики будут видны только залогиненым пользователям хабра? или всем, кто зайдет в блог .NET?
«Закрытый хабратопик, будет виден только подписчикам блога.» — только зарегистрированным
это не очень хорошо, учитывая отсутствие свободной регистрации на хабре…
По-другому у вас, наверное, не получится.
можно было бы задать в качестве следующего этюда )
пока я вижу только одно решение — дублировать в .NET в закрытом режиме и в персональном блоге — в открытом. Приемлемо ли такое на хабре?
Не видел такого. Я вообще не «бывалый» хабра. Это чисто мои рекомендации :)
многих и персональный лог не устроит, ибо он тоже может попасть на главную. В списке новых топиков он появтся. Продолжайте транслировать в блог .Net, ничего плохого в том, что в дотнете появляются новые интересные топики, я не вижу. :)
по крайней мере, в персональном блоге я буду чувствовать себя свободнее и писать то, что считаю нужным
спасибо за поддержку )
1. Test.aspx?ID=aaa — ~/PageA.aspx (сравниваются значения string)
2. Test.aspx?ID=bbb — ~/PageB.aspx
3. Test.aspx?ID=4 — ~/PageDafault.aspx (из-за первого условия в if)
4. Test.aspx?ID=10 — ~/Error.aspx (ошибка анбоксинга, long не int, должно быть точное соответствие)

а вот исправление — это больше вопрос философский :) если просто исправить для 10, то поменять long на int — просто не будет редиректа на Error.aspx. А все остальное — это от стремления к прекрасному зависит.

PS. в asp.net вообще ноль.
ответ неверный
конечно, знания ASP.NET тут играют существенную роль, но можно попытаться и общими методами догадаться
что по-Вашему делает Redirect и как бы Вы его написали, если бы Вам пришлось это делать?
Почитал про Redirect. Именно из-за него все будет идти в Error.aspx. А решение — я пока не знаю то, чего хотят :)
хочу, чтоб код работал так, как изначально предполагало большинство хабровчан (опуская детали), но с минимальными изменениями
Ну, если с минимальными изменениями, можно забить на это исключение
catch (ThreadAbortException)
{
}
catch (Exception)
{
Response.Redirect("~/Error.aspx");
}
да, замечательно )
Если я не ошибаюсь при таком решении сработает только запрос Test.aspx?ID=bbb (приведет на страницу "~/PageB.aspx")

В остальных случаях будет немного иначе:

— Test.aspx?ID=aaa приведет на Error.aspx — сравнение (object.ReferenceEquals(Request[«ID»], «aaa»)) естественно даст false и код соотвественно попадет на int i = int.Parse(Request[«ID»]), где выскочит FormatException.

— Test.aspx?ID=10 тоже приведет на Error.aspx — на месте ((long)boxedI == 10 выскочит InvalidCastException.

— Test.aspx?ID=4 приведет на PageDefault.aspx — тут немного интереснее. Вообще по аналогии с предыдущем запросом должна также сработать InvalidCastException, но так как первая часть условия (i > 5) при сравнении с 4 даст false, то в связи со спецификой оператора && (сокращенное вычисление) вторая часть условия проверяться вообще не будет. Если заменить строку сравнения на
((i > 5) & ((long)boxedI == 10)) — то выдаст ожидаемую InvalidCastException



Мне кажется по логике задачи ожидалась несколько другая функциональность.
логику Вы описали безупречно, но она надуманная, и предназначена, чтобы люди отвекли свое внимание и не заметили настоящего подвоха )
собственно, интернирование строк, неявное/явное приведение типа и короткая схема вычисления логических выражений — отвлекающий маневр, не более
смотрите ветку сразу после этой
НЛО прилетело и опубликовало эту надпись здесь
тогда это будет похоже не на загадку, а на лекцию…
НЛО прилетело и опубликовало эту надпись здесь
мне-то оно точно было интересным, когда я столкнулся с таким поведением )
а все запутывания помогают лучше передать реальную ситуацию
вот если бы я написал

try {Response.Redirect("~/PageA.aspx"); }
catch(Exception) {Response.Redirect("~/Error.aspx"); }

тогда бы конь был более сферическим))
Запустил таки код. Всегда на error.
Вообще говоря, я не понимаю, нафига этот квест с заведомо отвлекающей хернёй типа ReferenceEquals и боксинга, если решение по типу исключения гуглится в минуту.
ну кстати, посмотрите сколько на ReferenceEquals было вариантов, причем неправильных
конечно, я овлекающие вещи поставил, потому что не хотел, чтоб ответ через минуту появился )
Я написал себе вот такой класс:

public class QueryString
{
static public bool HasParam(string Name)
{
return Get(Name).Length > 0;
}

static public bool Equal(string Name, string Value)
{
return Get(Name).ToLower() == Value.ToLower();
}

static public string Get(string Name)
{
return Get(Name, "");
}

static public string Get(string Name, string DefaultVal)
{
string retVal = HttpContext.Current.Request.QueryString.Get(Name);

if (null == retVal)
retVal = DefaultVal;

return retVal;
}

static public int GetInt(string Name)
{
return GetInt(Name, 0);
}

static public int GetInt(string Name, int DefaultVal)
{
string strVal = Get(Name);
int val = DefaultVal;

if (!int.TryParse(strVal, out val))
val = DefaultVal;

return val;
}

static public long GetLong(string Name, long DefaultVal)
{
string strVal = Get(Name);
long val = DefaultVal;

if (!long.TryParse(strVal, out val))
val = DefaultVal;

return val;
}
}

Usage
protected void Page_Load(object sender, EventArgs e)
{
int Id = QueryString.GetInt(«id», -1);

или

return QueryString.Equal(«mode», «edit»);
да, многие так делают
но проблема совсем не в этом )
это скорее для отвлечения внимания
а зачем выдумывать такой код как в топике?
НЛО прилетело и опубликовало эту надпись здесь
если это ответ на самый первый вопрос, то он неправильный
хотя насчет интернирования, сравнения, короткой схемы логики и анбоксинга Вы правы )
кстати, интернировать можно и явно, а не только на этапе компиляции, но я почти уверен, что Вы это тоже знаете
НЛО прилетело и опубликовало эту надпись здесь
ну допустим, Вы считаете эти знания необязательными, я же придерживаюсь противоположной точки зрения )

как показала практика моих этюдов ), на хабре мои задачи решают довольно быстро, так что не вижу смысла здесь давать более простые. наоборот, стоит повышать уровень здесь сидящих, а не понижать

хотя если Вы уверены в своей задумке — никто не мешает попробовать ))
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
в общем случае согласен, но бывают и частности
например, писать 10 раз catch чтоб в каждом редирект на Error.aspx — тоже не очень красиво
НЛО прилетело и опубликовало эту надпись здесь
кстати, они в том проекте тоже используются, и даже правильно работают
здесь ситуация была в особенной логике для одной страницы
НЛО прилетело и опубликовало эту надпись здесь
у меня тоже есть задачка для вас уважаемые
вопрос на тройку:

int a = 12;
int b =32;

Response.Write((a * b).ToString()); каков результат? гггг

вопрос на 3+ ;)

Каков результат компиляции и выполнения приведенного ниже кода?

static void Main(string[] args)
{
Console.WriteLine(GetSomeResult(10000));
}

static long GetSomeResult(long someValue)
{
long value1 = 10 * 1000 * 10000 * someValue;
long value2 = 10 * 1000 * 10000 * 100000;
return value2 / value1;
}
ну второй известный прикол, все Ваши константы типа int, потому будет переполнение, несмотря на то, что тип переменной long
насчет результата компиляции не уверен, константы вычисляются в это время, но работатет ли там соответствующая опция — не знаю
исправить можно либо так: long value2 = 10L * 1000 * 10000 * 100000;
либо так: long value2 = unchecked(10 * 1000 * 10000 * 100000);
зависит от того, что именно Вам требуется

в первом подвоха не увидел, к сожалению (
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации