Импорт
От: Аноним  
Дата: 20.02.11 07:54
Оценка:
В COM'е была классная штука — идентификация интерфейсов по GUID'у. Две совершенно разных библиотеки, не имеющих явных ссылок друг на друга, могли быть клиентом и сервером, потому, что в обеих был описан один и тот же интерфейс с одним и тем же идентификатором. На C# с этим облом — надо референсить третью библиотеку, которая нужна только как хранилище интерфейсов. Является ли это свойством языка, или всего дотнета? Поскольку, если только языка, то было бы здорово иметь хотя бы в одном нормальном языке (N) возможность избежать манки-форсед ограничения. Необходимость таскать сборки с интерфейсами зачастую просто убивает.
Re: Импорт
От: hardcase Пират http://nemerle.org
Дата: 20.02.11 08:20
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Является ли это свойством языка, или всего дотнета?


В том-то и фича — эта третья библиотека позволят гарантировать то, что клиент и сервер работают с одинаковым интерфейсом.
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Импорт
От: Аноним  
Дата: 20.02.11 08:25
Оценка:
Здравствуйте, Аноним, Вы писали:

А>не имеющих явных ссылок друг на друга

COM уже порядком забыл, но общие заголовочные файлы-то надо было иметь и в составе клиента и в составе сервера.
Чем это не явные ссылки?

А>Необходимость таскать сборки с интерфейсами зачастую просто убивает

Чем это? Они же всегда заведомо маленькие.
Если напрягает количество сборок, то можно делать merge сборок в одну или несколько большего размера.

И, кстати, .NET поддерживает заведомо большую часть инфраструктуры COM.
Re[2]: Импорт
От: Аноним  
Дата: 20.02.11 16:29
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>не имеющих явных ссылок друг на друга

А>COM уже порядком забыл, но общие заголовочные файлы-то надо было иметь и в составе клиента и в составе сервера.
А>Чем это не явные ссылки?

Забыли. Нет, не надо было. Можно было независимо (на клиенте и сервере) описать интерфейс, привести указатель к этому интерфейсу и юзать. Надо было только знать GUID, чтобы было чего query.

А>>Необходимость таскать сборки с интерфейсами зачастую просто убивает

А>Чем это? Они же всегда заведомо маленькие.
А>Если напрягает количество сборок, то можно делать merge сборок в одну или несколько большего размера.

Тем, что это лишняя сущность. Одно дело сторонам обменяться гуидом, другое дело — целой сборкой, которую потом еще грузить. При работе со всякими SQLCLR или плагинными системами это вылезает постоянно.

А>И, кстати, .NET поддерживает заведомо большую часть инфраструктуры COM.


И?
Re[2]: Импорт
От: Аноним  
Дата: 20.02.11 16:39
Оценка:
Здравствуйте, hardcase, Вы писали:

А>>Является ли это свойством языка, или всего дотнета?

H>В том-то и фича — эта третья библиотека позволят гарантировать то, что клиент и сервер работают с одинаковым интерфейсом.

А знаете в чем фича отсутствия макросов в шарпе? Это позволяет гарантировать, что вообще все программисты будут работать с одинаковым набором синтаксических элементов.

Я только обрадовался, что залудили язык для нормальных пацанов, с макросами и всеми делами, и такой... манки-дривен аргумент.

Так это свойство платформы или языка? Когда вы приводите object к (IFoo) из другой сборки, можно эту работу в принципе выполнить не загружая ее?
Re[3]: Импорт
От: hardcase Пират http://nemerle.org
Дата: 20.02.11 17:00
Оценка:
Здравствуйте, Аноним, Вы писали:

A>Так это свойство платформы или языка?


Это свойство платформы.

А>Когда вы приводите object к (IFoo) из другой сборки, можно эту работу в принципе выполнить не загружая ее?


Нет Я думаю вам следует изучить принципы .NET, понятия сборок, систему типов.
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Импорт
От: Ziaw Россия  
Дата: 20.02.11 17:53
Оценка:
Здравствуйте, Аноним, Вы писали:

А>В COM'е была классная штука — идентификация интерфейсов по GUID'у. Две совершенно разных библиотеки, не имеющих явных ссылок друг на друга, могли быть клиентом и сервером, потому, что в обеих был описан один и тот же интерфейс с одним и тем же идентификатором. На C# с этим облом — надо референсить третью библиотеку, которая нужна только как хранилище интерфейсов. Является ли это свойством языка, или всего дотнета? Поскольку, если только языка, то было бы здорово иметь хотя бы в одном нормальном языке (N) возможность избежать манки-форсед ограничения. Необходимость таскать сборки с интерфейсами зачастую просто убивает.


Очередной фичреквест на duck typing. Платформа действительно не позволяет эффективно его реализовать? Хорошо бы подумать над этим.
Re[2]: Импорт
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 20.02.11 18:24
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Очередной фичреквест на duck typing. Платформа действительно не позволяет эффективно его реализовать? Хорошо бы подумать над этим.


DLR позволяет. Но я так чувствую, что для начала, надо взять макрос late и внаглую позиционировать его, как "впихнули невпихуемое", т.е. как реализацию динамической типизации безо всяких DLR.

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[4]: Импорт
От: Аноним  
Дата: 20.02.11 18:52
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Это свойство платформы.

А>>Когда вы приводите object к (IFoo) из другой сборки, можно эту работу в принципе выполнить не загружая ее?
H>Нет Я думаю вам следует изучить принципы .NET, понятия сборок, систему типов.

Это из-за IL-инструкции castclass?
Re[2]: Импорт
От: Аноним  
Дата: 20.02.11 19:24
Оценка:
Здравствуйте, Ziaw, Вы писали:

А>>В COM'е была классная штука — идентификация интерфейсов по GUID'у. Две совершенно разных библиотеки, не имеющих явных ссылок друг на друга, могли быть клиентом и сервером, потому, что в обеих был описан один и тот же интерфейс с одним и тем же идентификатором. На C# с этим облом — надо референсить третью библиотеку, которая нужна только как хранилище интерфейсов. Является ли это свойством языка, или всего дотнета? Поскольку, если только языка, то было бы здорово иметь хотя бы в одном нормальном языке (N) возможность избежать манки-форсед ограничения. Необходимость таскать сборки с интерфейсами зачастую просто убивает.


Z>Очередной фичреквест на duck typing. Платформа действительно не позволяет эффективно его реализовать? Хорошо бы подумать над этим.


Вообще-то, я имел в виду именно приведение интерфейсов. То есть, эффективность 100%. Но если верить hardcase, это невозможно. Что ж, если небольшое снижение производительности — та цена, которую надо заплатить, я лично готов.

Проблема, однако, вот в чем. DT должен поддерживаться на обоих концах. Допустим, есть IDispatch с Invoke(string MethodeName). Он должен входить в FW, чтобы и клиент, и сервер его видели (один дергал, другой реализовывал), пусть даже на клиенте язык позволяет прозрачно превращать вызовы в Invoke. Когда последний раз мне это было надо, я спрашивал на форуме .Net, есть ли какой-то подходящий интерфейс, ответ был — нету (действительно нет?). Как бы вы не реализовали DT, в это все упрется.
Re: Импорт
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 20.02.11 19:27
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Является ли это свойством языка, или всего дотнета?


FooLib1.dll:
namespace FooLib
{
  public class Class1
  {
    public WhoAmI() : string
    {
      "Class1 in FooLib1"
    }
  }
}


FooLib2.dll:
namespace FooLib
{
  public class Class1
  {
    public WhoAmI() : string
    {
      "Class1 in FooLib2"
    }
  }
}


Test.exe(FooLib1 и FooLib2 в референсах отсутствуют)
using Nemerle.Late;

using System;
using System.Reflection.Assembly;
using System.Console;

module Program
{
  Main() : void
  {
    def getInstance(assemblyName)
    {
      LoadFrom(assemblyName).CreateInstance("FooLib.Class1")
    }
    
    WriteLine(late getInstance("FooLib1.dll").WhoAmI());
    WriteLine(late getInstance("FooLib2.dll").WhoAmI());
    _ = ReadKey();
  }
}


Получаем:
Class1 in FooLib1
Class1 in FooLib2


Оно?

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[2]: Импорт
От: Аноним  
Дата: 20.02.11 20:02
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

А>>Является ли это свойством языка, или всего дотнета?


KV>Test.exe(FooLib1 и FooLib2 в референсах отсутствуют)

KV>
KV>using Nemerle.Late;

KV>using System;
KV>using System.Reflection.Assembly;
KV>using System.Console;

KV>module Program
KV>{
KV>  Main() : void
KV>  {
KV>    def getInstance(assemblyName)
KV>    {
KV>      LoadFrom(assemblyName).CreateInstance("FooLib.Class1")
KV>    }
    
KV>    WriteLine(late getInstance("FooLib1.dll").WhoAmI());
KV>    WriteLine(late getInstance("FooLib2.dll").WhoAmI());
KV>    _ = ReadKey();
KV>  }
KV>}
KV>


KV>Получаем:

KV>
KV>Class1 in FooLib1
KV>Class1 in FooLib2
KV>


KV>Оно?


Нет. Вам приходит на вход object, про который вы точно знаете, что он какой-нибудь IFoo и у него есть метод void Bar(). Его и надо вызвать, ничего не загружая.

Если вы имеете реф на сборку с IFoo, вы можете привести тип или вызвать оператор as, а потом вызывать Bar. А если нет? По идее, вы все знаете про IFoo. Полное имя типа, все сигнатуры, и пр. и др. Можете повторить этот интерфейс дословно и промаркировать его любыми атрибутами (RealTypeName[], например). Но поделиться этим знанием с компилятором не можете, не прибегая к загрузке внешней сборки, где тип описан.

Вопрос в том, можно ли это обойти на уровне языка (я бы посмотрел на реализацию того же as, но не владею IL, а разбираться нет времени), и если можно, то можно ли добавить в Nemerle. Раз авторы не побоялись ввести макросы, то язык занимает нишу "для смелых". Соответственно, сюда и вопрос.
Re[3]: Импорт
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 20.02.11 20:24
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Нет. Вам приходит на вход object, про который вы точно знаете, что он какой-нибудь IFoo и у него есть метод void Bar(). Его и надо вызвать, ничего не загружая.


Вообще-то, именно это и делает приведенный выше пример Test.exe ровным счетом ничего не знает о типе Class1 в обоих сборках, кроме его названия. Сборки же загружаются исключительно потому, что не загрузив их, крайне тяжело вызывать из них какие-либо методы

Вот пример попроще:

using Nemerle.Late;

using System;
using System.Console;

module Program
{
  class LengthableObject
  {
    public Length = 0
  }
  
  Main() : void
  {
    def getLength(o : object)
    {
      late o.Length;
    }
    
    WriteLine(getLength(array[1,2,3]));
    WriteLine(getLength([1,2,3,4,5]));
    WriteLine(getLength("bla-bla-bla"));
    WriteLine(getLength(LengthableObject()));
    _ = ReadLine();
  }
}

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[3]: Импорт
От: Ziaw Россия  
Дата: 20.02.11 20:34
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Здравствуйте, Ziaw, Вы писали:


Z>>Очередной фичреквест на duck typing. Платформа действительно не позволяет эффективно его реализовать? Хорошо бы подумать над этим.


KV>DLR позволяет. Но я так чувствую, что для начала, надо взять макрос late и внаглую позиционировать его, как "впихнули невпихуемое", т.е. как реализацию динамической типизации безо всяких DLR.


late это самая тормозная утиная типизация из всех возможных. Более эффективной будет создание прокси.

Решение в лоб:
IDuck
{
   Swim() : void;
}

SomeDuck
{
   public Swim():void {...}
}

[Record]
SomeDuckIDuckProxy : IDuck // Этот класс генерируется автоматически
{
   instance : SomeDuck;
   
   public Swim():void {instance.Swim()}
}

module Program()
{
   public Swim(duck : duck[IDuck])  : void   // передача утиного параметра
   {
      duck.Swim();
   }

   // должно развернуться во что-то типа:
   public Swim([DuckType(typeof(IDuck))] duckObj : object)  : void   // атрибут позволит компилятору проконтроллировать передачу сюда только тех типов, которые подходят под IDuck
   {
      def duck = DuckTyping.MakeProxy.[IDuck](duckObj);
      duck.Swim();
   }

   public Main() : void
   {
      def someDuck = SomeDuck();
      def duck = duck[IDuck](someDuck); // вот при таком использовании класс выше и должен сгенерироваться, в duck будет прокси
      // в итоге будет такой код
      def duck = SomeDuckIDuckProxy(someDuck) : IDuck; 

      Swim(someDuck); // Swim(SomeDuckIDuckProxy(someDuck)) // компилятор знает, что там потребуется IDuck, поэтому сразу передает то, что надо
      Swim(duck); // Swim(duck)
   }
}

module DuckTyping // Этот класс генерируется автоматически
{
   public MakeProxy[TDuck](o : object) : TDuck
   {
      if (o is TDuck)
         o :> TDuck             // чаще всего будет использована эта ветка
      else  match (typeof(TDuck), o.GetType())  // грубое описание
      {
         // тут у нас будет кусок кода который по таблице ищет
         | (typeof(IDuck), typeof(SomeDuck)) => SomeDuckIDuckProxy(o :> SomeDuck) :> TDuck 

         | _ => CreateRuntimeProxy(typeof(TDuck), o); // это самый тяжелый вариант, тип пришел из внешней сборки которая ничего про ducktyping не знает
      }
   }
}



Тут есть поле для оптимизаций, но уже такой duck typing должен быть быстрее DLR и, тем более, late.
Re[3]: Импорт
От: Ziaw Россия  
Дата: 20.02.11 21:20
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Проблема, однако, вот в чем. DT должен поддерживаться на обоих концах. Допустим, есть IDispatch с Invoke(string MethodeName). Он должен входить в FW, чтобы и клиент, и сервер его видели (один дергал, другой реализовывал), пусть даже на клиенте язык позволяет прозрачно превращать вызовы в Invoke. Когда последний раз мне это было надо, я спрашивал на форуме .Net, есть ли какой-то подходящий интерфейс, ответ был — нету (действительно нет?). Как бы вы не реализовали DT, в это все упрется.


Такой интерфейс не нужен, рефлекшен покрывает сценарии его использования. Но через рефлекшен все довольно небыстро получается. Похоже тебе не нужен DT, а действительно достаточно late.
Re[3]: Импорт
От: Воронков Василий Россия  
Дата: 21.02.11 07:58
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Нет. Вам приходит на вход object, про который вы точно знаете, что он какой-нибудь IFoo и у него есть метод void Bar(). Его и надо вызвать, ничего не загружая.


А как вы хотите вызвать метод Bar, не вызывая сборку, в которой он определен? Это нереально чисто физически. Или же речь идет о том, что у нас есть сбока А с интерфейсом IFoo, сборка B с реализацией IFoo, и вы хотите вызвать метод Bar у реализации, не загружая сборку с интерфейсом?

Так сделать можно. Причем довольно богатым набором способов. Однако за все эти способы придется платить производительностью. Причем, кстати, Немерле вам тут ничего не даст. Немерле дает богатые возможности для мета-программирования в компайл-тайме. Здесь же идет речь о мета-программировании в рантайме, с которым и у того же C# все в порядке. Единственно, что Немерле тут даст — это какой-нибудь синтаксический сахар на подобие late.

А саму вышеозначенную задачу можно решить:
— Напрямую через рефлекшин
— Через прозрачный прокси
— Через Emit (описать *свой* интерфейс IFoo, который *по сути* совместим с тем, который реализует наш Foo, но с т.з. рантайма это разные типы; затем сгенерить на лету обвертку для Foo, реализующую *свой* интерфейс IFoo). Этот способ с одной стороны самый быстрый, с другой стороны — самый медленный. На генерацию враппера уйдет какое-то время, зато потом вызовы будут осуществляться довольно быстро.
— Dynamic (C# 4.0)
Re[4]: Импорт
От: Аноним  
Дата: 21.02.11 09:44
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

А>>Нет. Вам приходит на вход object, про который вы точно знаете, что он какой-нибудь IFoo и у него есть метод void Bar(). Его и надо вызвать, ничего не загружая.


ВВ>А как вы хотите вызвать метод Bar, не вызывая сборку, в которой он определен? Это нереально чисто физически. Или же речь идет о том, что у нас есть сбока А с интерфейсом IFoo, сборка B с реализацией IFoo, и вы хотите вызвать метод Bar у реализации, не загружая сборку с интерфейсом?


Второе.

ВВ>Так сделать можно. Причем довольно богатым набором способов. Однако за все эти способы придется платить производительностью. Причем, кстати, Немерле вам тут ничего не даст. Немерле дает богатые возможности для мета-программирования в компайл-тайме. Здесь же идет речь о мета-программировании в рантайме, с которым и у того же C# все в порядке. Единственно, что Немерле тут даст — это какой-нибудь синтаксический сахар на подобие late.


ВВ>А саму вышеозначенную задачу можно решить:

ВВ>- Напрямую через рефлекшин
ВВ>- Через прозрачный прокси
ВВ>- Через Emit (описать *свой* интерфейс IFoo, который *по сути* совместим с тем, который реализует наш Foo, но с т.з. рантайма это разные типы; затем сгенерить на лету обвертку для Foo, реализующую *свой* интерфейс IFoo). Этот способ с одной стороны самый быстрый, с другой стороны — самый медленный. На генерацию враппера уйдет какое-то время, зато потом вызовы будут осуществляться довольно быстро.
ВВ>- Dynamic (C# 4.0)

Я плохой пример привел. Действительно, можно через рефлекшин даже на шарпе. Давайте другой приведу. Как подделать typeof(IFoo) для, например, ремотинга? Еще раз: вся информация нам на клиенте доступна. Гуиды-шмуиды, сигнатуры-шмигнатуры. Все. Выглядит так, что это 100% language hackable feature. Может, ошибаюсь.

IFoo obj = (IFoo) Activator.GetObject(typeof(IFoo), "tcp://localhost:666/service");
Re[4]: Импорт
От: Аноним  
Дата: 21.02.11 09:51
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Такой интерфейс не нужен, рефлекшен покрывает сценарии его использования. Но через рефлекшен все довольно небыстро получается. Похоже тебе не нужен DT, а действительно достаточно late.


IDispatch obj = (IDispatch) Activator.GetObject(typeof(IDispatch), "tcp://localhost:666/service");
Argument[] args = null;
object result;
obj.Invoke("Bar", args, out result);


????????? obj = (?????????) Activator.GetObject(?????????????????, "tcp://localhost:666/service");
Argument[] args = null;
object result;
obj.??????(???????????????????????);


Если клиент берет данные, необходимые в typeof() из третьей сборки, что-то подсказывает мне, что он мог бы брать их и из конфига, и из кода, и даже динамически от сервера через известный интерфейс.
Re[5]: Импорт
От: Аноним  
Дата: 21.02.11 10:24
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Я плохой пример привел. Действительно, можно через рефлекшин даже на шарпе. Давайте другой приведу. Как подделать typeof(IFoo) для, например, ремотинга? Еще раз: вся информация нам на клиенте доступна. Гуиды-шмуиды, сигнатуры-шмигнатуры. Все. Выглядит так, что это 100% language hackable feature. Может, ошибаюсь.


А>
А>IFoo obj = (IFoo) Activator.GetObject(typeof(IFoo), "tcp://localhost:666/service");
А>


Допустим, такое решение. На этапе компиляции выполняем typeof(IFoo). Побитовое представление полученного объекта сохраняем и зашиваем в сборку. Следовательно, в рантайме typeof можно больше не вызывать, т.к. есть зашитый. Получаем милую фичу "pseudo-reference" ("reference in design-time only").
Re[6]: Импорт
От: seregaa Ниоткуда http://blogtani.ru
Дата: 21.02.11 11:19
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Допустим, такое решение. На этапе компиляции выполняем typeof(IFoo). Побитовое представление полученного объекта сохраняем и зашиваем в сборку. Следовательно, в рантайме typeof можно больше не вызывать, т.к. есть зашитый. Получаем милую фичу "pseudo-reference" ("reference in design-time only").


А если попробовать сгенерировать аналогичное побитовое представление в рантайме?
Или даже так — с помощью емита сгенерировать на лету сборку с интерфейсом и подсунуть ее через AssemblyResolve
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.