LINUX.ORG.RU
Ответ на: комментарий от dave

Насчёт свойств и методов доступа, то здесь логика простая. Свойство используется там, где логика тривиальна, а метод там, где могут потребоваться серьёзные вычисления. Собственно, ничего не мешает на C# реализовывать методы доступа, как в Java. Я уже не говорю про индексаторы. То же касается и перегрузки. Любой инструмент нужно использовать по уму. Но то, что возможность есть, это хорошо. Array, так же, как и String - специфичный класс. Поэтому и сделаны методы, принимающие именно класс, а не интерфейс. Вероятно, JIT может более оптимально обработать массив, нежели абстрактный ICollection.

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

> Поэтому и сделаны методы, принимающие именно класс, а не интерфейс. Вероятно, JIT может более оптимально обработать массив, нежели абстрактный ICollection.

_Типизированный_ array - да, разумеется. Но Array вообще - это просто класс с перегруженным индексатором (который он на самом деле берет из IList). Т.е. по скорости разницы между доступом через IList.this[] или через Array.this[] быть не должно.

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

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

void f(string[] values) {...} а другое void f(array values) {...} В последнем случае это действительно выглядит не очень хорошо. И может быть оправдано, только если реализация существенным образом оптимизирована для работы с Array. Кстати, вспомнил ещё одну прикольную штуку, которая есть в C# - функции с произвольным числом аргументов. Понятно, что это просто синтаксическое удобство, но всё-таки.

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

> C# - функции с произвольным числом аргументов. Понятно, что это просто синтаксическое удобство, но всё-таки.

А вроде в пятое яве появилось тоже

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

Согласен на счет логики выбора между свойством и методом. Но порою, приходится крепко призадуматься, а "что же между ними все-таки выбрать"? В случае Java выбора - нет, поэтому немного проще :) Вообще, излишние возможности языка - это не только благо, но и почти всегда потенциальное зло. Кто-то красиво сказал: "недостатки - это продолжение наших достоинств." Насчет Array. Я думаю, в подобных местах имеет место быть просчет разработчиков, от чего, кстати, никто из нас не застрахован. Скажем, для той же оптимизации под тип Array можно было бы воспользоваться простой "перегрузкой" метода или, в крайнем случае, проверять Runtime-тип объекта.

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

>ообще, излишние возможности языка - это не только благо, но и почти всегда потенциальное зло

Только вот всё равно все используют С++ :)

Вообще, преимущества С# над явой следующие: 1. Перегрузка операций 2. Свойства 3. Делегаты 4. Аргументы по ссылке 5. Функции с переменнымколичеством аргументов 6. Оператор foreach 7. Более разумная, на мой вгляд, политика разрешения имёнования классов (пространств имён).

Преимущества Java: 1. inner-классы. Которые, кстати, используются в основном для организации обработки событий, и при использовании делегатов потребность в них возникает редко.

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

Поскольку мы тут говорим о 1.5, то бишь уже 5.0, то foreach и varargs в нем фигурируют. Сокращайте списочек =) А насчет inner-классов, так это можно и наоборот сказать: "при использовании inner-классов потребность в делегатах не возникает" ;)

Свойства - приятная фича, и их поддержка на уровне языка (без костылей в виде beans) радует, но не более того. Принципиально они ничего не дают. Перегрузка операторов - аналогично, считать что-то зубодробительное на яве вряд ли разумно, а так помимо BigInteger и BigNumber их и использовать-то особо негде. Аргументы по ссылке - уже обсудили =) Насчет пространств имен я, честно говоря, не понял - чем они принципиально отличаются от пакаджей?

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

> 1. Перегрузка операций

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

> 2. Свойства

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

> 3. Делегаты

Не нужны при наличии анонимных внутренних классов

> 4. Аргументы по ссылке

Да, иногда не хватает. Но в 90% случаев лечится аккуратным проектированием.

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

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

> 6. Оператор foreach

Уже. В 5.0

> 7. Более разумная, на мой вгляд, политика разрешения имёнования классов (пространств имён).

Можно подробнее?

svu ★★★★★
()
Ответ на: комментарий от 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 ★★★★
()
Ответ на: комментарий от 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 ★★★★★
()
Ответ на: комментарий от 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

> Это в смысле что надо бы 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 ★★★★
()
Ответ на: комментарий от svu

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

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

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

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

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

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

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

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

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

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

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