Защита С# от логических ошибок

 
0
 
.NET
ava
ivashkanet | 22.03.2006, 08:37
В теме Преобразование типов, товарища bankuss-а, была затронута тема преобразования типов (int в string).
По этому поводу велись большие дискуссии:
Например, такой код почему-то неработает в C#, а в VB -- работает.
Цитата


lk = (string) km;


Здесь lk -- string, km -- int.

Были даны комментарии (arilou):
Цитата


Данная строка означает "приведем переменную типа int к типу string". Для того, чтобы такая операция сработала, int должен стоять в цепочке наследования после string, либо string должен быть интерфейсом, который реализуется в классе int. Ни первое, ни второе не верно, поэтому операция приведения типа не работает.



После чего последовало много коментариев:

Цитата


arilou, иногда такие "мелочи" мешают работать! а для чего язык высокого уровня сделан? чтоб облегчить программистский труд а тут приходится тонну литературы прочитать прежде чем станет ясна проблема.... проще надо быть...



Цитата


Цитата



Цитата(bankuss @ 15.3.2006, 16:42 )


а для чего язык высокого уровня сделан






Честно - то, о чем ты говоришь реализовано в VB.NET. Но поверь мне, недостатков больше чем достоинств.



Это, как говориться, присказка, а сказка будет впереди.

Кто сможет, с ходу, без компиляции кода, решить задачку:
Дан простой код

int a = 10, b = 13;
string str = a + b;

Вопрос: какое значение примет str, и примет ли вообще?
Ответ пояснить (т.е. почему именно так, а не иначе).

P.S. Вечером дам правильный ответ и коментарии.
P.P.S. Просьба подумать самим, код не компелировать, только если для проверки
своей точки зрения.
P.P.P.S. mr.DUDA, arilou и другие модераторы,
не отвечайте, пожалуйста, на вопрос сразу. Потерпите, пожалуйста,
жотя бы до обеда. Не сбивайте интригу.
Ответы (19)
ava
FatherFrost | 22.03.2006, 10:24 #
Этот код вообще не скомпилится. Если ты напишешь:

int a = 10;
string str = a;

то компилятор тебе не даст это сделать. В своем задании ты предлагаешь сделать примерно тоже самое. Насколько я понял, объяснение этому уже дал arilou. Строка 2 в твоем задании по сути повторяет строку bankuss-а... Вот и все...
ava
Exception | 22.03.2006, 12:54 #
Имхо, данный код не скомпилится, поскольку ты присваиваешь int string'у без преобразования (хотя и оно все равно не получилось бы).
ava
ivashkanet | 22.03.2006, 14:21 #
Цитата (FatherFrost @ 22.3.2006, 10:24 findReferencedText)
Этот код вообще не скомпилится. Если ты напишешь:





код C#

1: 

2: 

int a = 10; 

string str = a; 





то компилятор тебе не даст это сделать. В своем задании ты предлагаешь сделать примерно тоже самое. Насколько я понял, объяснение этому уже дал arilou. Строка 2 в твоем задании по сути повторяет строку bankuss-а... Вот и все...


Цитата (Exception @ 22.3.2006, 12:54 findReferencedText)
Имхо, данный код не скомпилится, поскольку ты присваиваешь int string'у без преобразования (хотя и оно все равно не получилось бы)


Согласен, не скомпилируется!!!
Но вопрос "почему" остается открытый!!!
Ответы типа: нет яного или неявного преобразования, не принимаеться.
Ведь ввести его, как это сделано в VB, могу даже я сам!!!

Явное:

public static implicit operator string(int intValue)
{
return intValue.ToString();
}

Или неявное:

public static explicit operator string(int intValue)
{
return intValue.ToString();
}



Так печему же не сделали это разработчики???
Вот в чем вопрос???
Почему они отказались от явного или неявного преобразования????


P.S. Можно глянуть в название темы.
ava
Domestic Cat | 22.03.2006, 15:39 #
Потому что непонятно, что ты хочешь сделать строкой

string str = a + b;

- то ли сложить два числа и далее инициализировать стринг ("23"), то ли получить "1013". Отсутствие неявной конвертации в стринг по-моему более безопасно. Никто не мешает написать например

string str = string.Format("{0}{1}", a, b);

или

string str = (a + b).ToString();

В общем, не понимаю в чем проблема.
ava
mr.DUDA | 22.03.2006, 15:56 #
Интересно, почему тогда вот так можно:
using System;

class TestApp
{
static void Main()
{
string s = "";
int a = 10, b = 13;
s += a + b; // "23"
}
}

:qstn
ava
ivashkanet | 22.03.2006, 16:10 #
Цитата (Domestic Cat @ 22.3.2006, 15:39 findReferencedText)
Потому что непонятно, что ты хочешь сделать строкой



string str = a + b;



- то ли сложить два числа и далее инициализировать стринг ("23"), то ли получить "1013". Отсутствие неявной конвертации в стринг по-моему более безопасно. Никто не мешает написать например

Именно

Вот это я и хотел сказать.
Что С# -- язык, в котором уже на этапе компиляции должны отпадасть все неопределенности и двусмысленности!!! ;-)

И хочу поделиться, увиденным мною, принципом языка C#:

Если запись может трактоваться двусмысленно -- то она не должна присутствовать в языке!!! Программист должен явно указать, что он хочет сделать.


Например, если добавить пустую строку в начало:

int a = 2, b = 134;
string s;
s = "" + a + b;

то все будет хорошо (str+int = str) и результат будет "2134"
А если в конец:

int a = 2, b = 134;
string s;
s = "" + a + b;

то int +int = int, int + str =str и результат будет "136"

То есть двусмысленность отпала (раз мы используем "", то явно результат строка)

P.S. В общем мне понравилась строгость языка C# и я захотел поделиться этим с другими.
А то бывает неделю ищешь ошибку, а она рассмотренного типа :hmmm.

P.P.S. Всем спасибо. Я люблю C#. Прям балдею.
ava
ivashkanet | 22.03.2006, 16:49 #
Цитата (mr.DUDA @ 22.3.2006, 15:56 findReferencedText)
Интересно, почему тогда вот так можно:



using System; 

class TestApp

{
  static void Main() 
  {
  string s = ""; 
  int a = 10, b = 13; 
  s += a + b; // "23" 
  }

}



Тут скорее всего такая ситуация:

s+=a;

эквивалентно записи

s=s+a;

str + int = str -- все пуском smile
А код

s += a + b;

скорее всего соответствует коду

s= s + (a + b);

Скобки стоят потому, что в операторе += сначала считается правая часть, а потом она добавляется к переменной слева.
И вообще += нет в операторах C#, он скорее всего обрабатыветься при синтаксическом разборе кода.
P.S. mr.DUDA, пока писал прозевал твое сообщение.
ava
mr.DUDA | 22.03.2006, 16:59 #
ivashkanet, так это всё ясно. Непонятно, почему при конкатенации строки с int-ом идёт неявное преобразование int->string, а при присваивании - нет smile
Добавлено позднее:
З.Ы, ещё я хотел бы попросить не злоупотреблять ОГРОМНЫМ шрифтом - в глазах рябит smile
ava
ivashkanet | 22.03.2006, 17:22 #
Ну так написано ж

Цитата (Domestic Cat @ 22.3.2006, 15:39 findReferencedText)
Потому что непонятно, что ты хочешь сделать строкой



string str = a + b;



- то ли сложить два числа и далее инициализировать стринг ("23"), то ли получить "1013".


А int + str -- все ясно: str к int не приведешь, поэтому однозначно нужно приводить int к str.
ava
mr.DUDA | 22.03.2006, 17:32 #
Цитата (ivashkanet @ 22.3.2006, 16:22 findReferencedText)
А int + str -- все ясно: str к int не приведешь, поэтому однозначно нужно приводить int к str.

вот это "нужно" почему-то не совсем ясно почему именно оно нужно smile
ava
ivashkanet | 22.03.2006, 17:45 #
Цитата (mr.DUDA @ 22.3.2006, 17:32 findReferencedText)
вот это "нужно" почему-то не совсем ясно почему именно оно нужно

Не понял, поясни.

P.S. Каждый оператор что-то должен делать. У этого только два варианта (см. выше), из которых первый бессмысленный. smile
ava
mr.DUDA | 22.03.2006, 18:32 #
Цитата (ivashkanet @ 22.3.2006, 16:45)
Цитата (mr.DUDA @  22.3.2006, 17:32 \\"findReferencedText\\")
вот это "нужно" почему-то не совсем ясно почему именно оно нужно


Не понял, поясни.



P.S. Каждый оператор что-то должен делать. У этого только два варианта (см. выше), из которых первый бессмысленный. smile

В языке, в котором синтаксисом запрещено приведение int к string, не должно быть неявного приведения в частном случае. Если и так не понятно, то вот тебе код:
using System;

class TestApp
{
static void Main()
{
string s = "";
s = s + 10; // компилируется !
s = s + (string)10; // не компилируется ! error CS0030
}
}

Я считаю, что такое несоответствие - это недоработка компилятора.
ava
ivashkanet | 22.03.2006, 19:07 #
Цитата (mr.DUDA @ 22.3.2006, 18:32 findReferencedText)
Я считаю, что такое несоответствие - это недоработка компилятора.

Может ты и прав, у каждого свое мнение.
Но на мой взгляд неопределенности и двуссмысленности нет.
Поэтому можно его сделать неявным.

Цитата (mr.DUDA @ 22.3.2006, 18:32 findReferencedText)
В языке, в котором синтаксисом запрещено приведение int к string, не должно быть неявного приведения в частном случае.

Хотя..., только сейчас подумал, почему не сделать явное преобразование int в strins вся ответственность в этом случае ложится на программиста :qstn .

P.S. mr.DUDA, не оскверняй светлый лик C# (шутка) smile .
ava
mr.DUDA | 22.03.2006, 19:11 #
Цитата (ivashkanet @ 22.3.2006, 18:07 findReferencedText)
Но на мой взгляд неопределенности и двуссмысленности нет.

Поэтому можно его сделать неявным.


Цитата (ivashkanet @ 22.3.2006, 18:07 findReferencedText)
P.S. mr.DUDA, не оскверняй светлый лик C# (шутка)


C# - это ведь не PHP, где всё можно ;-)
ava
ivashkanet | 22.03.2006, 19:16 #
Цитата (mr.DUDA @ 22.3.2006, 19:11 findReferencedText)
C# - это ведь не PHP, где всё можно

PHP ниразу не видел :(
ava
mr.DUDA | 22.03.2006, 19:24 #
Цитата (ivashkanet @ 22.3.2006, 18:16 findReferencedText)
PHP ниразу не видел

так вот, там и не такие выкрутасы возможны:

$num1 = 123; // int
$num2 = 0.93845; // float
$str = $num1 + $num2 + "aaa" + true;
if($str) {...}
ava
ivashkanet | 22.03.2006, 19:47 #
Цитата (mr.DUDA @ 22.3.2006, 19:24 findReferencedText)
$str = $num1 + $num2 + "aaa" + true;

И чё интересно в $stк будет???? (Теряюсь в догадках :notify )

P.S. Это чем-то напоминает мне Perl в котором вообще нет типов переменных :hehe
ava
ivashkanet | 22.03.2006, 20:54 #
По логике будет true
1) num+num =123.93845
2) num+"aaa" = "123.93845aaa" // скорее всего
3) "123.93845aaa" + true = true // "123.93845aaa"<>"" => true

Но енто бред. :exclamation
ava
Exception | 22.03.2006, 21:19 #
Честно говоря, после работы с VB6 рад, что в VB .NET/C# запрещено такое неявное преобразование. Не раз обламывался на нём.
Зарегистрируйтесь или войдите, чтобы написать.
Фирма дня
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Участники
advanced
Отправить