Полиморфизм области видимости
От: GlebZ Россия  
Дата: 02.11.05 18:46
Оценка:
Здраствуйте, All.
Че-то меня задолбало обсуждение и перемывание косточек в райне оптимизации. Решил вспомнить об одной мысли. Об extension.

Как бы все вначале выглядит благообразно. Существует статический метод с параметром this.
//файл xml.cs
namespace xml
{
  public class MyExtension
    {
          //
        public static void ToDB(this string source) 
                {...};
    }
}
//файл db.cs
namespace db
{
  public class MyExtension
    {
          //суммирует через базу данных
        public static void ToDB(this string source) 
                {...};
    }
}
//использование первого в файле бла1.cs
using xml;
.....
string str="bla1";
str.ToDB();
//использование второго возможно только в другом файле, например бла2.cs
using db;
........
string str="bla2";
str.ToDB();

То есть, управление расширением типа только с помощью using(для сишников сообщаю — аналог include). Как бы расширение типа вещь крутая и весьма нужная. Но ограничения убивают все что можно.
Во первых одно расширение на весь исходный файл. В результате в одной процедуре нельзя обратиться к различным расширениям, и в результате получается неприятная вещь. Мы можем сохранять либо в xml, либо в DB. Если нужно поддерживать обоих, то нужно делать вторую процедуру в другом файле.
Во-вторых существуют крутые рефакторинги которые переносят код из файла в файл. И процедура просто может запутаться, потому как она не может учесть особенности куда сохраняется, в xml или db. Нет возможности узнать кто же в данный момент подключен.
Ситуацию конечно легко решить если бы разработчики компилятора внедрили более управляемые области видимости, что-то типа with и is_with.
Ну например:
//проверяем подключен-ли namespace DB
is_with(DB)
{
  string str="DB forever";
  str.ToDB();
}

или сознательно переключиться на DB
with(DB)
{
  str.ToDB();
}

И ессно два вопроса. Существуют ли языки с полиформизмом зависящим от области видимости? И может кто-нибудь объяснит мне какой вред может быть от таких дополнительных конструкций.(про то что это синт. сахар для Net2.0 пока забудим).

С уважением, Gleb.
PS. ессно понимаю что можно сделать другими средствами. Но как-то за державу обидно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Полиморфизм области видимости
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 03.11.05 08:19
Оценка: 23 (2)
Здравствуйте, GlebZ, Вы писали:

GZ>
GZ>//проверяем подключен-ли namespace DB
GZ>is_with(DB)
GZ>{
GZ>  string str="DB forever";
GZ>  str.ToDB();
GZ>}
GZ>

GZ>или сознательно переключиться на DB
GZ>
GZ>with(DB)
GZ>{
GZ>  str.ToDB();
GZ>}
GZ>

GZ>И ессно два вопроса. Существуют ли языки с полиформизмом зависящим от области видимости?



Ruby

Имхо, не совсем то, что тебе нужно, но в Ruby можно делать так:
module Xml
    def to_db
        puts "#{self} going to XML"
    end
end

module Db
    def to_db
        puts "#{self} going to DB"
    end
end

str1 = String.new( "bla1" )
str1.extend Xml

str2 = String.new( "bla2" )
str2.extend Db

str1.to_db
str2.to_db


получаем:
bla1 going to XML
bla2 going to DB


Это пример подмешивания Mixin-а к уже существующему объекту.
Не совсем то, о чем ты говорил потому, что это интрузивное подмешивание. У объекта str2 уже нельзя будет изъять метод to_db, даже если объект str2 перейдет в другую область видимости.

Тем не менее твоя конструкция with(DB) {str.ToDB();} выполняет то же самое, что и str2.extend Db; str2.to_db.



C++

#include <iostream>
#include <string>

namespace Xml
{
    inline void to_db( const std::string & s )
        {
            std::cout << s << " going to XML" << std::endl;
        }
}

namespace Db
{
    inline void to_db( const std::string & s )
        {
            std::cout << s << " going to DB" << std::endl;
        }
}

int main()
    {
        std::string str( "bla" );

        {
            using namespace Xml;
            to_db( str );
        }

        {
            using namespace Db;
            to_db( str );
        }
    }


получаем:

bla going to XML
bla going to DB


Хотя это уже и не расширение объекта.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: Полиморфизм области видимости
От: buriy Россия http://www.buriy.com/
Дата: 03.11.05 08:28
Оценка: +1
Здравствуйте, GlebZ, Вы писали:

GZ>И ессно два вопроса. Существуют ли языки с полиформизмом зависящим от области видимости? И может кто-нибудь объяснит мне какой вред может быть от таких дополнительных конструкций.(про то что это синт. сахар для Net2.0 пока забудим).

Полиформизма, зависящего от области видимости, скорее всего нет — нахрена он нужен?
Почему не подходит взять скриптовый язык (Python, Javascript, кажется Ruby тоже), в котором можно просто поменять метод объекта класса "на лету"? Ну или например AOP для Java и .NET, в котором можно сделать то же самое.
Почему бы просто не подумать над твоей идеей и не довести ее до ума?
/bur
Re: Полиморфизм области видимости
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.11.05 10:43
Оценка: 15 (1) +3
Здравствуйте, GlebZ, Вы писали:

GZ>Здраствуйте, All.

GZ>Че-то меня задолбало обсуждение и перемывание косточек в райне оптимизации. Решил вспомнить об одной мысли. Об extension.

GZ>Как бы все вначале выглядит благообразно.

Никакого благообразия я не вижу. Расширения — очень специфическая штука. Всегда надо помнить, что они расширяют сигнатуру некоторого конкретного класса. С этой точки зрения наличие одноименных расширений для одного и того же класса — нонсенс. Ты же не скучаешь по возможности дописать два одинаковых метода ToDB в свой класс MyString?
В данном случае методы должны называться ToDB и ToXml. И нуль проблем.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Полиморфизм области видимости
От: GlebZ Россия  
Дата: 03.11.05 11:49
Оценка:
Здравствуйте, Sinclair, Вы писали:

GZ>>Как бы все вначале выглядит благообразно.

S>Никакого благообразия я не вижу. Расширения — очень специфическая штука. Всегда надо помнить, что они расширяют сигнатуру некоторого конкретного класса. С этой точки зрения наличие одноименных расширений для одного и того же класса — нонсенс.
Или интерфейса. И в концепции LINQ где расширяется IEnumerator до вида когда им можно пользоваться, оно вполне вписывается. Если бы не те вещи, которые описал вначале.
S>Ты же не скучаешь по возможности дописать два одинаковых метода ToDB в свой класс MyString?
S>В данном случае методы должны называться ToDB и ToXml. И нуль проблем.
Я такой пример сделал из-за простоты и наглядности.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Полиморфизм области видимости
От: GlebZ Россия  
Дата: 03.11.05 12:44
Оценка:
Здравствуйте, eao197, Вы писали:

E>Это пример подмешивания Mixin-а к уже существующему объекту.

E>Не совсем то, о чем ты говорил потому, что это интрузивное подмешивание. У объекта str2 уже нельзя будет изъять метод to_db, даже если объект str2 перейдет в другую область видимости.
Да, это несколько не то.

E>

E>C++
[skipped]
E>Хотя это уже и не расширение объекта.
Блин, а то что using в С++ имеет scope я забыл. Очень похожая штука. Только более мощная. Это конечно не расширение, но похожие вещи делать можно.
Вообще в extension значительно важнее не то, что может расширяться класс, а то что может расширяться интерфейс. Это значительно полезней.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Полиморфизм области видимости
От: OnThink Россия http://vassilsanych.livejournal.com
Дата: 03.11.05 13:35
Оценка: +1 -1
имхо ГРЯЗНЫЙ ХАК
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Полиморфизм области видимости
От: GlebZ Россия  
Дата: 03.11.05 13:49
Оценка:
Здравствуйте, OnThink, Вы писали:

OT>имхо ГРЯЗНЫЙ ХАК

А что тут грязного? Чисто как стеклышко. Другой вопрос пользоваться этим нельзя.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Полиморфизм области видимости
От: GlebZ Россия  
Дата: 03.11.05 14:24
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Расширения — очень специфическая штука.

IMHO А вообще эта штука будет удобна не только для интерфейсов, но и для классов сгенеренных после кодогенерации.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Полиморфизм области видимости
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.11.05 10:21
Оценка:
Здравствуйте, GlebZ

Я вот как раз наткнулся на необходимость "расширить" описание типа. Может быть, это как-то можно было сделать и по другому (кстати, интересно, как?), но я просто воспользовался возможностями Ruby для расширения типов.

Итак, пишу сейчас генератор C++ кода на Ruby из Ruby-же деклараций. В процессе обработки деклараций должны создаваться объектики-генераторы и куда-то укладываться. Для этого я сделал класс для хранения всех зарегистрированных генераторов:
class Generators

    @@generators = {}

    def Generators.add( file_name, generator ) ... end

    def Generators.all_files ... end

    def Generators.for_file( file_name ) ... end

end # class Generators


Статическая член @@generators является закрытой частью Generators, а статические методы add(), all_files() и for_file() -- его public-интерфейс. Все, вроде бы, нормально. Но вот при unit-тестинге нужно получать доступ к @@generators для того, чтобы непосредственно управлять содержимым списка генераторов (для имитирования различных ситуаций).

Возникает вопрос: как дать тестам возможность работать с @@generators, но не расширять при этом публичный интерфейс Generators?
В C++ бы я мог использовать friend:
class Generators {
    friend class TC_CodegenInitiator;
    friend class TC_Generators;
private :
    //! Методы только для "своих".
    static void test_setup() { ... }
    static GeneratorsMap & test_all_generators() { ... };
public :
    //! Методы для всех остальных.
    ...
};

Но и в C++ не очень удобно: при добавлении нового TestCase нужно добавлять его имя в описание класса Generators.

В Ruby я сделал дополнение к классу Generators:
class Generators
    def Generators.test_setup
        @@generators = {}
    end
    def Generators.test_all_generators
        @@generators
    end
end

Это дополнение подгружается в unit-тестах и делаем возможным работу непосредстванно с @@generators.

Вот такое вот применение возможности расширения типов.




В качестве возможных обходных путей для того же C++, наверное, можно было бы использовать следующие приемы:

1. Объявить в классе Generators статический член generatos в виде protected-члена:
class Generators {
    protected :
        static GeneratorsMap generators;
    ...
};

а в unit-тестах использовать производный от Generators класс:
class ExtendedGenerators : public Generators {
    public :
        static void test_setup() { generators.clear(); }
        static GeneratorsMap & test_all_generators() { return generators; }
};


2. Определить Generators как интерфейс и реализовать доступ к нему через паттер Singleton.
class Generators {
    public :
        virtual void add(...) = 0;
        virtual const FileMap & all_files() = 0;
        virtual Generator & for_file(...) = 0;
        
        static Generators * instance();
};

Затем создать штатную реализацию Generators но сделать ее интерфейс расширенным:
class StdGenerators : public Generator {
    public :
        ...
        void test_setup() { ... }
        void GeneratorsMap & test_all_generators() { ... };
};

И в unit-тестах использовать знания о StdGenerators:
StdGenerators * g = dynamic_cast< StdGenerators * >( Generators::instance() );
g->test_setup();
...



В общем, все это хаки. Только в Ruby, имхо, этот хак самый простой.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Полиморфизм области видимости
От: GlebZ Россия  
Дата: 05.11.05 07:19
Оценка: +2
Здравствуйте, eao197, Вы писали:

E>В общем, все это хаки. Только в Ruby, имхо, этот хак самый простой.

Это точно. Только в C#3 это не хак, так как расширение не нарушает инкапсуляцию классов. Это всего лишь статические методы которые можно вызывать как внутренние методы расширяемого объекта. Доступа к private/protected он не имеет.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Полиморфизм области видимости
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.11.05 05:41
Оценка: 6 (1) +1
Здравствуйте, GlebZ, Вы писали:
S>>В данном случае методы должны называться ToDB и ToXml. И нуль проблем.
GZ>Я такой пример сделал из-за простоты и наглядности.

Чего-то я не понимаю. Попробую объяснить еще раз: расширения не предназначены для быстрого переключения реализаций. Быстрое переключение реализуется некоторыми другими, вполне незатейливыми паттернами.
Расширения — очень статическая штука. Когда ты проектируешь расширение, нужно отдавать себе отчет, что оно "необратимо" изменит сигнатуру расширяемого типа. И по-хорошему надо позаботиться о том, чтобы имена методов были достаточно осмысленными и не конфликтовали с другими потенциальными расширениями.

Best practice: человек, который читает твой код, не обязан знать о наличии екстеншна. Ему все должно быть понятно и так. Если он встречает код типа:

a.ToDB();

, то у него не должно возникать вопросов о семантике.

Worst Practice: реализация "статического полиморфизма" при помощи смены подключаемой сборки или выбора области видимости. Первое еще куда ни шло — гарантирует целостность семантики в пределах всего проекта. Второе — тихий ужас. Именно потому, что отследить, что за код где вызывается, очень тяжело. А если бы это сделали в пределах одного файла, то была бы вообще труба.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Полиморфизм области видимости
От: GlebZ Россия  
Дата: 07.11.05 10:32
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Чего-то я не понимаю. Попробую объяснить еще раз: расширения не предназначены для быстрого переключения реализаций.

Проблема не в том, что не предназначены. Проблема в том, что запрещены. То есть расширять в конкретном случае можно, но переключать запрещено. При той же сигнатуре. Такие расширения сразу становятся практически нереализуемыми.
S>Быстрое переключение реализуется некоторыми другими, вполне незатейливыми паттернами.
Ага. Легко делается генериком + незатейлевым делегированием.

S>Расширения — очень статическая штука. Когда ты проектируешь расширение, нужно отдавать себе отчет, что оно "необратимо" изменит сигнатуру расширяемого типа. И по-хорошему надо позаботиться о том, чтобы имена методов были достаточно осмысленными и не конфликтовали с другими потенциальными расширениями.

В том-то и дело, что нет никакой возможности управления разрешениями конфликтов. Я именно об этом и говорю. И о том, что она слишком статическая штука.

S>Worst Practice: реализация "статического полиморфизма" при помощи смены подключаемой сборки или выбора области видимости. Первое еще куда ни шло — гарантирует целостность семантики в пределах всего проекта. Второе — тихий ужас. Именно потому, что отследить, что за код где вызывается, очень тяжело. А если бы это сделали в пределах одного файла, то была бы вообще труба.

Насчет второго, В условиях когда ты это делаешь в одной сборку — есть более управляемые методы(хотя бы через сам расширяемый тип). Этот вопрос даже рассматривать не стоит. А вот насчет первого случая, то это имеет право на жизнь. И очень даже хорошую жизнь учитывая что расширяется не реализация а сигнатура. Но сейчас это действительно худо. Поэтому я и мечтаю о более управляемом полиформизме. Пока же, это и полиформизмом трудно назвать.
Кстати, было бы неплохо если бы расширения могли добавлять не только методы, но и методы удовлетворяющии некоторому интерфейсу.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Полиморфизм области видимости
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.11.05 12:25
Оценка:
Здравствуйте, GlebZ, Вы писали:
S>>Чего-то я не понимаю. Попробую объяснить еще раз: расширения не предназначены для быстрого переключения реализаций.
GZ>Проблема не в том, что не предназначены. Проблема в том, что запрещены. То есть расширять в конкретном случае можно, но переключать запрещено. При той же сигнатуре. Такие расширения сразу становятся практически нереализуемыми.
Гм. Ничего не понимаю. Какие расширения становятся практически нереализуемыми? Которые не надо реализовывать?
GZ>В том-то и дело, что нет никакой возможности управления разрешениями конфликтов. Я именно об этом и говорю. И о том, что она слишком статическая штука.
Вопрос, конечно, интересный. Пока что рано говорить о практике применения штуки, которая еще даже официального статуса не получила. Тем не менее, нутряное чутье мне подсказывает, что управлять разрешениями конфликтов скорее всего вообще не понадобится. Если народ не станет клепать расширения всего подряд направо и налево.
S>>Worst Practice: реализация "статического полиморфизма" при помощи смены подключаемой сборки или выбора области видимости. Первое еще куда ни шло — гарантирует целостность семантики в пределах всего проекта. Второе — тихий ужас. Именно потому, что отследить, что за код где вызывается, очень тяжело. А если бы это сделали в пределах одного файла, то была бы вообще труба.
GZ>Насчет второго, В условиях когда ты это делаешь в одной сборку — есть более управляемые методы(хотя бы через сам расширяемый тип). Этот вопрос даже рассматривать не стоит.
Нет. Я имею в виду, что у тебя есть сборка A, в которой реализован екстеншн, к примеру, для IEnumerable.ToString(string format). И есть сборка B, которая реализует этот экстеншн по-другому. И ты используешь в своем проекте либо сборку A, либо сборку B. Но никогда не подключаешь обе!
GZ>А вот насчет первого случая, то это имеет право на жизнь. И очень даже хорошую жизнь учитывая что расширяется не реализация а сигнатура.
GZ>Но сейчас это действительно худо.
Не понял. Первое — это же подмена сборки
GZ>Поэтому я и мечтаю о более управляемом полиформизме. Пока же, это и полиформизмом трудно назвать.
Конечно. Весь полиморфизм здесь сводится к тому, что сам класс может перекрыть метод из расширения. Т.е. мы можем, к примеру, сделать расширение int GetCount() для IEnumerable. А в некоторых классах, реализующих IEnumerable, мы бы сделали свой GetCount, без перебора. Вот тебе и весь полиморфизм — частная реализация для конкретного класса + fallback для базового класса/интерфейса.
GZ>Кстати, было бы неплохо если бы расширения могли добавлять не только методы, но и методы удовлетворяющии некоторому интерфейсу.
Угу. Это были бы уже не расширения, а примеси. А как бы это вообще работало? На каком этапе? Мы же не можем объявить наш класс реализующим некоторый интерфейс в надежде на то, что клиент подключит подходящую реализацию — нихрена не скомпилируется. Если мы делаем екстеншн, то на каком этапе он вступит в игру? На этапе, когда я приведу объект моего класса к интерфейсу? Фигня выходит:

MyObject mo = new MyObject();
ISome i = (ISomeObject)mo // здесь компилер еще может понять, что надо применить екстеншн для MyObject
object o = mo;
ISome i2 = (ISomeObject)o; // а вот здесь уже поехал cast на уровне MSIL, а он про наш сахар ничего не знает.

Косяк, однако.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Полиморфизм области видимости
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.11.05 12:50
Оценка:
Здравствуйте, GlebZ, Вы писали:

E>>Это пример подмешивания Mixin-а к уже существующему объекту.

E>>Не совсем то, о чем ты говорил потому, что это интрузивное подмешивание. У объекта str2 уже нельзя будет изъять метод to_db, даже если объект str2 перейдет в другую область видимости.
GZ>Да, это несколько не то.

Вот здесь я, как оказалось, соврал. В Ruby у класса можно удалить ранее объявленный метод: Re[12]: С++ culture
Автор: eao197
Дата: 07.11.05
.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: Полиморфизм области видимости
От: GlebZ Россия  
Дата: 07.11.05 13:14
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>>>Чего-то я не понимаю. Попробую объяснить еще раз: расширения не предназначены для быстрого переключения реализаций.

GZ>>Проблема не в том, что не предназначены. Проблема в том, что запрещены. То есть расширять в конкретном случае можно, но переключать запрещено. При той же сигнатуре. Такие расширения сразу становятся практически нереализуемыми.
S>Гм. Ничего не понимаю. Какие расширения становятся практически нереализуемыми? Которые не надо реализовывать?
Извини, неверно выразился. Использовать такие расширения практически нельзя. Получается некоторая бессмысленная игрушка.

S>Вопрос, конечно, интересный. Пока что рано говорить о практике применения штуки, которая еще даже официального статуса не получила. Тем не менее, нутряное чутье мне подсказывает, что управлять разрешениями конфликтов скорее всего вообще не понадобится. Если народ не станет клепать расширения всего подряд направо и налево.

Не-а. Направо и налево клепать их не надо. Но в некоторых случаях — расширения просто неоценимы. Простое решение декоратора.

S>Нет. Я имею в виду, что у тебя есть сборка A, в которой реализован екстеншн, к примеру, для IEnumerable.ToString(string format). И есть сборка B, которая реализует этот экстеншн по-другому. И ты используешь в своем проекте либо сборку A, либо сборку B. Но никогда не подключаешь обе!

Не-а. Ничего криминального в таких сборках нет. У тебя есть интерфейс, и есть некоторый метод с той-же сигнатурой. Зафигом знать особенности реализации. Не наше собачье дело. Наше собачье дело сказать с помощью namespace что мы хотим работать с базой данных, или с xml.

S>Не понял. Первое — это же подмена сборки

absolutly right. Только слово переключение мне больше нравится. Сборки с расширением — равноценны.
GZ>>Поэтому я и мечтаю о более управляемом полиформизме. Пока же, это и полиформизмом трудно назвать.
S>Конечно. Весь полиморфизм здесь сводится к тому, что сам класс может перекрыть метод из расширения.
Нее, перекрыть нельзя. И imho это правильно. Если есть метод подходящий в реальном типе, то компилятор плюет на все расширения.

GZ>>Кстати, было бы неплохо если бы расширения могли добавлять не только методы, но и методы удовлетворяющии некоторому интерфейсу.

S>Угу. Это были бы уже не расширения, а примеси. А как бы это вообще работало? На каком этапе? Мы же не можем объявить наш класс реализующим некоторый интерфейс в надежде на то, что клиент подключит подходящую реализацию — нихрена не скомпилируется. Если мы делаем екстеншн, то на каком этапе он вступит в игру? На этапе, когда я приведу объект моего класса к интерфейсу? Фигня выходит:
S>
S>MyObject mo = new MyObject();
S>ISome i = (ISomeObject)mo // здесь компилер еще может понять, что надо применить екстеншн для MyObject
S>object o = mo;
S>ISome i2 = (ISomeObject)o; // а вот здесь уже поехал cast на уровне MSIL, а он про наш сахар ничего не знает.
S>

S>Косяк, однако.
Ууу, ты сразу полез в синтаксис. К сожалению нет возможности самому расширению протестироваться что он удовлетворяет некоторому стандарту расширений. А клиенту об этом расскажет компилятор на уровне методов.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Полиморфизм области видимости
От: GlebZ Россия  
Дата: 07.11.05 13:24
Оценка: +1
Здравствуйте, eao197, Вы писали:

GZ>>Да, это несколько не то.


E>Вот здесь я, как оказалось, соврал. В Ruby у класса можно удалить ранее объявленный метод: Re[12]: С++ culture
Автор: eao197
Дата: 07.11.05
.

Принциальная разница в том, что расширения ни в коем случае не аналог наследования ни mixin. Они никак не могут влиять на исходный тип. Они не могут ни нарушать инкапсуляцию, ни перекрывать методы, ни удалять их. У тебя тогда есть 100 процентная гарантия что исходный тип будет работать в исходном виде.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Полиморфизм области видимости
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.11.05 15:27
Оценка:
Здравствуйте, GlebZ, Вы писали:
GZ>Извини, неверно выразился. Использовать такие расширения практически нельзя.
Гм. Опять 26. Какие "такие"? Пока что я вижу трудности при попытке есть суп вилкой. Использовать экстеншны для того, для чего они предназначены, легко и приятно.
GZ> Получается некоторая бессмысленная игрушка.
Неа. Я уже вижу миллион применений этой бессмысленной игрушке. И ни в одном из них не видится никаких проблем с одноименностью расширений. Я просто не захочу сосуществования двух разных экстеншнов с одинаковой сигнатурой.

Боюсь, я не смогу продолжать конструктивную дискуссию ежели ты не представишь сценарии использования, в которых это было бы полезно. Про ToDB/ToXML я на своем уровне понимания уже ответил.
GZ> Не наше собачье дело. Наше собачье дело сказать с помощью namespace что мы хотим работать с базой данных, или с xml.
Бред. Не надо говорить о своих намерениях с помощью NameSpace.
Более того, я считаю дурным тоном играть с областями видимости в таких целях и безо всяких екстеншнов. Вот плохой пример:

using namespace Test;
namespace Test1
{
  public class SomeClass : Test.ISomeInterface
    {
      int ISomeInterface.A { get { return 1; }
    }
}


using namespace Test;
namespace Test2
{
  public class SomeClass : Test.ISomeInterface
    {
      int ISomeInterface.A { get { return 1; }
    }
}


Играем с огнем:
using Test;
using Test2;
public class MyClass
{
  private static SomeClass _sc = new SomeClass();
    public static int GetA()
    {
      return _sc.A;
    }
}

Без анализа строки using Test2; мы не можем понять, что имеется в виду под SomeClass.
Более конкретный пример вымышленных граблей (приведены fully qualified class names):
System.Data.Common.DbConnection
System.Data.SqlClient.DbConnection
System.Data.OracleClient.DbConnection

Пример того, как пишут на самом деле (к счастью!):
System.Data.Common.DbConnection
System.Data.SqlClient.SqlConnection
System.Data.OracleClient.OracleConnection

Видишь? А то ведь можно было бы переключаться между реализациями при помощи соответствующего юзинга!
GZ>Нее, перекрыть нельзя. И imho это правильно. Если есть метод подходящий в реальном типе, то компилятор плюет на все расширения.
Плевание — это и есть собсно "перекрытие" дефолтной реализации.
GZ>>>Кстати, было бы неплохо если бы расширения могли добавлять не только методы, но и методы удовлетворяющии некоторому интерфейсу.
GZ>Ууу, ты сразу полез в синтаксис.
Конечно. Рассуждения без синтаксиса — это как у Пруткова: "Отчего ж сразу не изобрели порох непромокаемым?"
GZ>К сожалению нет возможности самому расширению протестироваться что он удовлетворяет некоторому стандарту расширений.
Зато можно легко написать юнит-тест
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Полиморфизм области видимости
От: GlebZ Россия  
Дата: 07.11.05 16:11
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Гм. Опять 26. Какие "такие"? Пока что я вижу трудности при попытке есть суп вилкой. Использовать экстеншны для того, для чего они предназначены, легко и приятно.

Я уже писал. Допустим, у меня есть класс работы с некоторой коллекцией объектов. Я не очень понимаю что эта коллекция объектов из-себя представляет. Это может быть IEnumerator от XLinq, или допустим от DLinq, или просто от Linq. Но абстрагироваться от того, с кем я работаю у меня возможности нет. Я могу работать только с одной из этих библиотек.
GZ>> Получается некоторая бессмысленная игрушка.
S>Неа. Я уже вижу миллион применений этой бессмысленной игрушке. И ни в одном из них не видится никаких проблем с одноименностью расширений. Я просто не захочу сосуществования двух разных экстеншнов с одинаковой сигнатурой.
А они уже есть. Linq, DLinq, XLinq.

S>Боюсь, я не смогу продолжать конструктивную дискуссию ежели ты не представишь сценарии использования, в которых это было бы полезно. Про ToDB/ToXML я на своем уровне понимания уже ответил.

Назови метод ToStorage. Достаточно абстрактное название которое абстрагирует вызывающего от знания внутренностей используемой библиотеки экстеншинов.
GZ>> Не наше собачье дело. Наше собачье дело сказать с помощью namespace что мы хотим работать с базой данных, или с xml.
S>Бред. Не надо говорить о своих намерениях с помощью NameSpace.
Linq именно на этом и построен.
S>Более того, я считаю дурным тоном играть с областями видимости в таких целях и безо всяких екстеншнов.

[skipped]
Перепиши его по другому(в твоем варианте компилятор будет ругаться):
using Test;
using Test2;
public class MyClass
{
//абстрагируемся от реализации через интерфейс.
  private static ISomeInterface _sc=new Test.SomeClass() as ISomeInterface;
    public static int GetA()
    {
      return _sc.A;
    }
}


S>Без анализа строки using Test2; мы не можем понять, что имеется в виду под SomeClass.

S>Более конкретный пример вымышленных граблей (приведены fully qualified class names):
S>
S>System.Data.Common.DbConnection
S>System.Data.SqlClient.DbConnection
S>System.Data.OracleClient.DbConnection
S>

S>Пример того, как пишут на самом деле (к счастью!):
S>
S>System.Data.Common.DbConnection
S>System.Data.SqlClient.SqlConnection
S>System.Data.OracleClient.OracleConnection
S>

Не-а. Тут наглядность классов реализаций. Но нельзя же запретить полностью работать через интерфейсы IDBxxxxx и абстрагироваться от типа бд. И при этом у тебя есть рычажок проверить с какой базой работаешь, и учесть это в конкретных местах. Чего не присутсвует в Linq.

GZ>>Нее, перекрыть нельзя. И imho это правильно. Если есть метод подходящий в реальном типе, то компилятор плюет на все расширения.

S>Плевание — это и есть собсно "перекрытие" дефолтной реализации.
Не понял что ты здесь имел ввиду.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Полиморфизм области видимости
От: GlebZ Россия  
Дата: 07.11.05 18:14
Оценка:
Здравствуйте, GlebZ, Вы писали:

Ладно, я уже понял одну вещь. Как не выпендривайся, абстрагироваться экстеншоны не дадут. И в том числе при работе с LINQ нельзя абстрагироваться от типа хранилища. Вобщем все ублюдочно получается.
Лучше бы они о более вменяемых примесях подумали.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.