LINUX.ORG.RU

Ответ на: комментарий от Eugene_Korobko

Не только
Вообще говоря, inner классы используются для эмуляции closures. 
Очень удобная штука получается.

Пример

public class DBAccess {

    public interface Consumer {
        public void consume (ResultSet rs) throws SQLException;
    }

    public static void executeQuery (String query, Object[] params, Consumer c)
         throws SQLException {
        /// blahblahblah
    }

}

в клиенте

DBAccess.executeQuery ("select 'val' value from dual", null, 
          new DBAccess.Consumer ()
          {
             public void consume (ResultSet rs) throws SQLException {
                  System.out.println (rs.getString ("VALUE"));
             }
          });

В общем, почти схема, только синтаксис не такой удобный

anonymous
()
Ответ на: комментарий от svu

> Причина огромного количества граблей в С++ коде. Вряд ли это лучше в С#.

А вы проверьте =) На самом деле, ни разу еще не видел кривого использования перегрузки операторов в C#-коде. Зато это позволяет на уровне языка задать такие вещи, как сложение строк плюсом, и индексацию массивов. А в яве как-то непонятно - тот же плюс для строк переопределен (чем не operator overloading?), а вот сравнение - нет. Я уж молчу про BigInteger/BigNumber.

> Реально, это перекликается с перезагрузкой операторов. Тот же синтаксический сахар, те же потенциальный грабли.

Приведите пример конкретных (пусть и потенциальных) граблей, связанных с property accessors (как это более правильно было бы называть, ибо свойства - они и у JavaBeans свойства).

> > 5. Функции с переменнымколичеством аргументов

> Да, хорошо бы...

Вроде бы это добавили в 5.0?

int19h ★★★★
()
Ответ на: комментарий от svu

> Я не знал, что в 5.0 разрешили varargs. Как это-то удалось уложить, не ломая байткода?

Почитайте JSR201 (http://www.jcp.org/en/jsr/detail?id=201). Хоть в его названии varargs не упоминаются, но они в него входят. Если вкратце - это суть syntactic sugar для метода, последним параметром которого является массив. Т.е. следущие два объявления с точки зрения VM есть одно и то же:

void printf(String format, Object... args);

void printf(String format, Object[] args);

Больше того, vararg-методу можно вместо N аргументов передать один массив.

int19h ★★★★
()
Ответ на: комментарий от int19h

Собственно, вот суть жабских vararg'ов, изложенная в спецификации:

"If the last formal parameter is a variable arity parameter of type T, it is considered to define a formal parameter of type T[]. The method is then a variable arity method. Otherwise, it is a fixed arity method. Invocations of a variable arity method may contain more actual argument expressions than formal parameters. All the actual argument expressions that do not correspond to the formal parameters preceding the variable arity parameter will be evaluated and the results stored into an array that will be passed to the method invocation"

int19h ★★★★
()

Спрашивал в соседнем форуме, но никто не ответил. Вот тут говорят, что .NET поддерживает VB, C++ и огромное количество других языков. Но позвольте, VB.NET и managed C++.NET - это вовсе не VB и не C++, а просто некие вариации синтаксиса для C#. Другие языки тоже поддерживаются путем создания нестандартных расширений? Тогда какой в этом смысл - писать код на C++, а интерфейсы на C++.NET? Но ведь тогда код становится unmanaged?

anonymous
()
Ответ на: комментарий от svu

Любая языковая конструкция - это потенциальные грабли. Совйтсва - не исключение. Грамотное использование позволяет сделать код более аккуратным. Да и индексеры - полезная штука. Что касается делегатов, то мне они нравятся больше. Как-то аккуратнее. Помните, какой геморрой в паскале со встроенными функциями? А наследовать класс от listener'a, и добавлять себя к списку получателей сообщения от себя же - это что? Я не понимаю аргументов в том духе, что "можно и без этого обойтись". Можно, конечно. Наличие параметров по ссылке это преимущество? Безусловно. Так в чём возражение заключается? Что касается пространств имён - мне не нравится их привязка к доменному имени в интернете. Кстати, показательно, что в раздел "преимущества явы" вы ничего не дописали;

Eugene_Korobko
()
Ответ на: комментарий от int19h

> А вы проверьте =)

Ой, это надо mono ставить - была печаль...:) Да, сложение строк в жабе - это действительно безобразие.

> Приведите пример конкретных (пусть и потенциальных) граблей, связанных с property accessors (как это более правильно было бы называть, ибо свойства - они и у JavaBeans свойства).

Вся эта игра с перегрузкой - это игра на человеческих ассоциациях. А у людей ассоциации могут быть разные:). Впрочем, для пропертей это не очень актуально. Меня напрягает другое. Если я пишу a.b = c - мне каждый раз прикажете думать - это просто присвоение или что-то большее? Уж если я хочу большего, я сразу скажу a.setB(c) - сразу виден вызов метода. Сразу думаешь про стОимость метода, побочные эффекты и пр. Попытки запихать это дело "под коврик" кончаются программами, в которых пользователи внутреннего API совершенно не задумываются о том, что лучше сделать

int i = a.getB(); int j = i + 1; int k = i + 2;

вместо

int i = a.b; int j = a.b + 1; int k = a.b + 2;

Заметание реальных вещей "под коврик" (иначе говоря, syntax sugar) - иногда выходит боком.

svu ★★★★★
()
Ответ на: комментарий от anonymous

> VB.NET и managed C++.NET - это вовсе не VB и не C++, а просто некие вариации синтаксиса для C#

Насчет VB вы правы. Но вот C++ - это несколько другое дело... действительно, там много новых ключевых слов, и CLR-compliant интерфейсы весьма ограничены в плане использования конструкций языка (те же шаблоны), но вот внутри вы можете творить все что душе угодно - шаблоны, STL, множественное наследование... при этом код _остается_ managed (но unsafe, насколько я помню).

int19h ★★★★
()
Ответ на: комментарий от Eugene_Korobko

> Наличие параметров по ссылке это преимущество? Безусловно

С этим я согласился. Просто считаю это преимущество обладающим очень небольшим весом.

> Кстати, показательно, что в раздел "преимущества явы" вы ничего не дописали;

Дык я не о том говорил. А о преимуществах C#, которых ИМХО почти нет:) Для меня лично главное идеологическое преимущество жабы (оборачивающееся проблемами с производительностью) - отсутствие указателей.

svu ★★★★★
()
Ответ на: комментарий от Eugene_Korobko

Делегаты - действительно вещь полезная, но, по моему, внутренние классы практически равнозначное решение. А насчет свойств - операция доступа к свойству как и любая функция, в отличии, скажем, от операции доступа к аттрибуту, может теоретически выбросить исключение. Соответственно, при беглом взгляде на код для меня это будет вовсе неочевидно.

anonymous
()
Ответ на: комментарий от svu

> Да, сложение строк в жабе - это действительно безобразие.

Это в смысле что надо бы a.add(b.add(c)) вместо a+b+c, или вы на неявный toString() жалуетесь?

> Если я пишу a.b = c - мне каждый раз прикажете думать - это просто присвоение или что-то большее?

А вам не надо об этом думать. В том и фишка свойств - они скрывают такую _деталь реализации_, как необходимость выполнения дополнительных действий при изменении атрибута объекта (например, перерисовку виджета при изменении надписи на нем).

> Уж если я хочу большего, я сразу скажу a.setB(c) - сразу виден вызов метода. Сразу думаешь про стОимость метода, побочные эффекты и пр.

То-то жабщики никогда не делают переменные public, и всегда оборачивают их в пару get/set. И потом мы видим такой вот замечательный код, как:

int value = 0;

int getValue() { return this.value; }

int setValue(int value) { this.value = value; }

Стомость метода? Побочные эффекты, да? ;)

int19h ★★★★
()
Ответ на: комментарий от anonymous

Еще раз насчет свойств: уже давно пришли к тому, что прямой доступ к переменным-членам (за исключением this.foo) - это не есть хорошо, и для каждой переменной делают пару get/set методов, даже если они просто изменяют/возвращают ее значение. При таком раскладе вы тоже не знаете, кто может кинуть ексепшн, а кто нет.

int19h ★★★★
()
Ответ на: комментарий от int19h

Интересно, могу я в managed C++.NET коде выделить память по new и освободить по delete? По моему, новые ключевые слова и означают нестандартное расширение - то есть это уже не C++, так что говорить, что .NET поддерживает C++ формально нельзя imho. Видимо и с остальными языками так же.

anonymous
()
Ответ на: комментарий от anonymous

> Интересно, могу я в managed C++.NET коде выделить память по new и освободить по delete?

Да.

> По моему, новые ключевые слова и означают нестандартное расширение - то есть это уже не C++, так что говорить, что .NET поддерживает C++ формально нельзя imho.

Можно. Можно взять _любую_ C++-программу и скомпилить в байткод. И оно будет работать. Но вот если ты пишешь библиотеку, с public-классами и методами, или же используешь .NET-классы - тут уже придется пользоваться расширениями языка.

int19h ★★★★
()
Ответ на: комментарий от int19h

> Это в смысле что надо бы a.add(b.add(c)) вместо a+b+c, или вы на неявный toString() жалуетесь?

Если запретили операторы - тогда a.add(b).add(c).add(d) (как в StringBuffer - там же append - и никто не плачет - тем более, что если строки конкатенируются, то рекомендуется пользовать все-таки StringBuffer, а не String).

> они скрывают такую _деталь реализации_,

Сам факт, что дополнительные действия производятся - мне кажется, скрывать опасно. Какие это действия - действительно не очень важно. Но там внутри что-то есть. И это бывает полезно знать - для оценки производительности. Опять же, пример с exceptions - тоже хороший. Ничего не делал, только присваивал - и вдруг схлопотал exception...

> такой вот замечательный код, как:

Вы забыли расставить protected/public:)) Если серьезно - да, так и надо. Потому как в дочернем классе setValue еще и каких-нибудь listeners оповещать будет про изменение соотв. проперти. А то еще и кто-нибудь из listeners сделает veto - тогда вообще весь set насмарку... И всю эту мощь и кучу работы вы замели под a.value = value? И предлагаете не думать о таких мелочах (кстати, а exception в случае veto - тоже не ловить?)

svu ★★★★★
()
Ответ на: комментарий от svu

Вы меня не совсем поняли. Просто в случае с явой, все изменения атрибутов делаются через setXXX(), и соответственно от _каждого_ из них вы вправе ожидать каких-либо побочных эффектов (в том числе exceptions). Так вот со свойствами в C# - та же ситуация. То есть когда вы пишете "foo.x = y", вы _обязаны_ предполагать, что там могут быть и побочные эффекты, и exceptions. В конечном итоге, разницы совершенно никакой.

int19h ★★★★
()
Ответ на: комментарий от int19h

Чтобы еще наглядней: представьте, что в яву добавили syntactic sugar, позволяющий автоматически создать
простую пару public get/set для переменной. Пусть это будет ключевое слово "autowrap". Теперь посмотрим на
один и тот же код на яве и C#:

// Java
class Foo {

  // это просто переменная, без побочных эффектов
  private int x;
  public autowrap x;

  // а вот тут мы уже что-то делаем
  private int y;
  public int getY() { ...; return this.y; }
  public int setY(int y) { ...; this.y = y; }
}

Foo foo;
foo.setX(foo.getX() + 1);
foo.setY(foo.getY() + 1);


// C#
class Foo {

  // это просто переменная, без побочных эффектов
  public int X;

  // а вот тут мы уже что-то делаем
  private int y;
  public int Y {
    get { ...; return this.y; }
    set { ...; this.y = value; }
}

Foo foo;
foo.X = foo.X + 1;
foo.Y = foo.Y + 1;


Ну как, большая разница в возможности определения побочных эффектов и эксепшенов?

int19h ★★★★
()
Ответ на: комментарий от int19h

>Но вот если ты пишешь библиотеку, с public-классами и методами, или же используешь .NET-классы - тут уже придется пользоваться расширениями языка.

А какой тогда смысл в C++ программе под .NET если всего этого не делать. Мне на ум приходят только какие-нибудь расчетные задачи. Хотя, конечно, определенный плюс в этом всем есть.

anonymous
()
Ответ на: комментарий от svu

> А-а. Тогда да. Пессимистичное проектирование. Ожидание худшего. Тогда конечно:))

Так вы и в яве, когда getXXX делаете, тоже всегда вынуждены худшее ожидать =)

int19h ★★★★
()
Ответ на: комментарий от anonymous

> А какой тогда смысл в C++ программе под .NET если всего этого не делать.

А смысл в том, что маркетоиды могут потом гордо говорить о "поддержке более чем двадцати языков" =) На самом деле, разумеется, все эти языки приходится, иногда довольно серьезно, обрабатывать напильником, втискивая в рамки .NET. Все "нестандартные" фичи остаются за бортом межъязыкового взаимодействия, а без него - зачем оно вообще все надо?

Собственно поэтому я и говорю, что весь этот хваленый .NET multilanguage support - это довольно бестолковая штука. Как под JVM пишут на яве, так и под .NET будут писать на C# (ну и VB.NET, который суть тот же C# с более расслабленными правилами проверки типов и несколько измененным синтаксисом; я, зная C#, "освоил" VB.NET за день, когда понадобилось проект делать на нем)

int19h ★★★★
()
Ответ на: комментарий от int19h

Это все хорошо при доступе снаружи класса, а внутри:

Вот я пишу: for( int r = 0; r < Count; r++ ) или for( int r = 0; r < getCount(); r++ ) - второй вариант сразу вызовет подозрения в смысле оптимальности - первый будет скорее всего пропущен.

anonymous
()
Ответ на: комментарий от int19h

getXXXX - да, конечно, может быть кошмаром на улице вязов. А просто

int b = this.b;

не лишит меня ночного сна:)

svu ★★★★★
()
Ответ на: комментарий от anonymous

> Это все хорошо при доступе снаружи класса, а внутри

А при доступе внутри, это же ваш класс - вот и обращайтесь к переменным, а не к свойствам =) Тем более что, следуя майкрософтовким naming conventions, их легко различить - this.Count это свойство, а thus.count - просто переменная.

int19h ★★★★
()
Ответ на: комментарий от Eugene_Korobko

Честно говоря, мой список преимуществ C# над Java (v5.0) несколько отличается и сводится только к двум пунктам:

1. Структуры (можно еще их назвать light-weight objects).

2. Делегаты.

Хотя, как тут неоднакратно было замечено, делегаты можно свести к inner-классам, но все же предыдущие иногда приятнее на вид...

Но в целом, я бы сказал, что C# и Java очень близки и похожи как языки.

Наверное, более интересным было бы сравнение стандартных библиотек, сопровождающих обе платформы. Например, "GDI+ против Java 2D" или "XMLReader из .NET против SAX из JAXP". Ну, в общем, что-то в таком духе. :)

dave ★★★★★
()
Ответ на: комментарий от svu

> не лишит меня ночного сна:)

Так и меня в C# не лишит. Я же знаю, что она переменная - потому как с маленькой буквы начинается, и к тому же, если на нее мышой в VS.NET навести, оно так и скажет: "int b" ;)

int19h ★★★★
()
Ответ на: комментарий от dave

> XMLReader из .NET против SAX из JAXP

Вот XmlReader имхо однозначно лучше. Не люблю callback'и там, где им явно не место. Особенно если при желании их все равно можно будет потом прикрутить.

int19h ★★★★
()
Ответ на: комментарий от int19h

А-а.. Мышкой.. В VS.NET.... humor.filtered.lor :))

svu ★★★★★
()
Ответ на: комментарий от int19h

Вообще, это чистой воды вкусовщина :) Так свойства не вызывали у меня отторжения, когда я писал на Delphi - в паскале и так можно опускать скобки при вызове функции без параметров. А C++ - вызывают, по той же самой причине - что это идет вразрез с привычной семантикой языка :)

anonymous
()
Ответ на: комментарий от anonymous

> Вообще, это чистой воды вкусовщина :)

... что я и пытаюсь доказать на протяжении последних десяти (или около того) постов =)

int19h ★★★★
()
Ответ на: комментарий от dave

>Структуры (можно еще их назвать light-weight objects).

Ага, особенно неявный boxing/unboxing :) Эта штука посильней Фауста Гете

anonymous
()
Ответ на: комментарий от anonymous

> Сегдня наш, завтра ваш :) Или Вы не знаете как это бывает? :)

Честно - на практике не знаю. Не довелось еще участвовать в чем-то мало-мальски большом, или поддерживать чужой код.

Но догадываюсь. В свете чего предлагается лозунг: "Долой vim из инструментария Java-разработчика! Даешь современные IDE с браузерами классов и всплывающими подсказками!" ;)

int19h ★★★★
()
Ответ на: комментарий от anonymous

> Ага, особенно неявный boxing/unboxing :)

Да ладно. Просто к лозунгу java-программеров, "Memory is cheap!", .NET-программеры дописали еще одну строчку: "So is CPU!" =)

int19h ★★★★
()
Ответ на: комментарий от int19h

:)) Это я хотел смухлевать - сделать ставку после начала матча:))

svu ★★★★★
()
Ответ на: комментарий от Eugene_Korobko

>> Хотя бы прикол с невозможностью написания на яве функции, которая переставляет местами два int'а.

swap two integers ;-) a^ = b^ = a^ = b;

anonymous
()
Ответ на: комментарий от anonymous

> swap two integers ;-) a^ = b^ = a^ = b;

... и оптимизатор выпадает в осадок...

int19h ★★★★
()
Ответ на: комментарий от Eugene_Korobko

> Кстати, в C# 2 появились анонимные методы. По сути то же, что и inner классы.

Не совсем. У inner-класса, кроме методов, могут же быть еще и переменные. Да и методов может быть несколько, так что можно красиво группировать те же обработчики для виджетов по классам.

Но в целом, действительно, особой разницы не будет.

int19h ★★★★
()
Ответ на: комментарий от int19h

> На самом деле, ни разу еще не видел кривого использования перегрузки операторов в C#-коде.

+= это самое оно для листенеров. Читабельность возростает на порядки...

И вообще давайте там где что-то кудато кладется будем += использовать. Во прикольно будет....

r ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.