Информация об изменениях

Сообщение Re[90]: Java vs C# vs C++ от 11.10.2015 21:08

Изменено 11.10.2015 21:21 Serginio1

Здравствуйте, -MyXa-, Вы писали:

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


S>>
S>> public object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] argsOrig, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
S>>        {        // Unwrap any AutoWrap'd objects (they need to be raw if a paramater)

S>>            if (name == "[DISPID=-4]")
S>>            {
S>>                return new EnumVariantImpl(((IEnumerable)O).GetEnumerator());
S>>            }
MX>        [поскипана куча]
S>>


MX>Дай угадаю, "[DISPID=-4]" — это С-шный

MX>
MX>#define    DISPID_NEWENUM    ( -4 )
MX>

Это запрос комовского Энумератора.
MX>Это ты придумал со строкой сравнивать, или это работа мастера?
Это нетовская работа с диспинтерфейсами. Обычно Кроме инвоке идут GetIDsOfNames

MX>Но, вообще, это не код, это... короче, C# — ассемблер современности.


MX>Ты уверен, что как ты написал — так это и должно делаться?

Это используется уже кучу лет.

MX>На Visual C++ ты напишешь типа того:


MX>
MX>[
MX>    object,
MX>    dual // Это разрешает поддержку IDispatch
MX>]
MX>interface MyInterface
MX>{
MX>    // твои методы
MX>};

MX>[
MX>    coclass,
MX>    default(MyInterface)
MX>]
MX>class MyClass
MX>{
MX>    // реализации методов
MX>};
MX>

MX>А при твоём подходе события поддерживаются? События — такая же стандартная фича, как и IDispatch (см. IConnectionPoint и атрибут event_source).

MX>И если ты всё руками делаешь — tlb откуда возьмётся?

А зачем tlb? Tcnm ITypeInfo. Да и Idispatch и он не нужен. 1С прекрасно без него обходится

Со свойствами проблема, но их можно динамически обернуть. То есть сделать обертку над классом для описания свойв.
Для простых случаев можно так.
 [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
  //  [Guid("33B45C9D-1AED-41F9-8880-36AB6AE84749")]
    public interface IEventFor1C
    {
        [DispId(0x60020000)]
        void Событие();

        [DispId(0x60020001)]
        void СобытиеСПараметром(object value);
    }

   

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [Guid("62F8156C-13B9-4484-B152-82023243E1D3")]
    [ComSourceInterfaces(typeof(IEventFor1C))]
    public class ClassForEvent1C
    {
        [ComVisible(false)]
        public delegate void Событие_Delgate();
        public delegate void СобытиеСПараметром_Delgate(object value);
        public object Объект;
        private SynchronizationContext Sc;

        public ClassForEvent1C(object Объект,String СобытиеОбъекта,bool ЕстьПараметр=false)
        {
            this.Объект = Объект;
            BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
            EventInfo ei = Объект.GetType().GetEvent(СобытиеОбъекта, bf);
              if (!ЕстьПараметр)
            ei.AddEventHandler(Объект, new System.Action(ВнешнееСобытие));
             else
            ei.AddEventHandler(Объект, new System.Action<object>(ВнешнееСобытиеСПараметром));

            SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
            Sc = SynchronizationContext.Current;

        }
        public event Событие_Delgate Событие;
        public event СобытиеСПараметром_Delgate СобытиеСПараметром;
       
        private void ВнешнееСобытие()
        {
          if (this.Событие != null) //Событие();
              Sc.Send(d => Событие(), null);

        
        }

        
        private void ВнешнееСобытиеСПараметром(object value)
        {
            if (this.СобытиеСПараметром != null) //Событие();
                Sc.Send(d => СобытиеСПараметром(AutoWrap.ОбернутьОбъект(value)), null);


        }

    }



Либо пишу ручками используя анонимные типы. И подписка
 void OnGetMessageImage(object value);




 wa.OnGetMessageImage += (mediaNode, from, id, fileName, fileSize, url, preview) =>
            {
                ОтослатьСобытиеСПараметром(OnGetMessageImage, new { mediaNode = mediaNode, from = from, id = id, fileName = fileName, fileSize = fileSize, url = url, preview = preview }, "OnGetMessageImage");
            };
Здравствуйте, -MyXa-, Вы писали:

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


S>>
S>> public object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] argsOrig, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
S>>        {        // Unwrap any AutoWrap'd objects (they need to be raw if a paramater)

S>>            if (name == "[DISPID=-4]")
S>>            {
S>>                return new EnumVariantImpl(((IEnumerable)O).GetEnumerator());
S>>            }
MX>        [поскипана куча]
S>>


MX>Дай угадаю, "[DISPID=-4]" — это С-шный

MX>
MX>#define    DISPID_NEWENUM    ( -4 )
MX>

Это запрос комовского Энумератора.
MX>Это ты придумал со строкой сравнивать, или это работа мастера?
Это нетовская работа с диспинтерфейсами. Обычно Кроме инвоке идут GetIDsOfNames

MX>Но, вообще, это не код, это... короче, C# — ассемблер современности.


MX>Ты уверен, что как ты написал — так это и должно делаться?

Это используется уже кучу лет.

MX>На Visual C++ ты напишешь типа того:


MX>
MX>[
MX>    object,
MX>    dual // Это разрешает поддержку IDispatch
MX>]
MX>interface MyInterface
MX>{
MX>    // твои методы
MX>};

MX>[
MX>    coclass,
MX>    default(MyInterface)
MX>]
MX>class MyClass
MX>{
MX>    // реализации методов
MX>};
MX>

MX>А при твоём подходе события поддерживаются? События — такая же стандартная фича, как и IDispatch (см. IConnectionPoint и атрибут event_source).

MX>И если ты всё руками делаешь — tlb откуда возьмётся?

А зачем tlb? Есть ITypeInfo котрый и реализуется во врапере методы IReflect. Да и Idispatch и он не нужен. 1С прекрасно без него обходится

Со свойствами проблема, но их можно динамически обернуть. То есть сделать обертку над классом для описания свойв.
Для простых случаев можно так.
 [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
  //  [Guid("33B45C9D-1AED-41F9-8880-36AB6AE84749")]
    public interface IEventFor1C
    {
        [DispId(0x60020000)]
        void Событие();

        [DispId(0x60020001)]
        void СобытиеСПараметром(object value);
    }

   

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [Guid("62F8156C-13B9-4484-B152-82023243E1D3")]
    [ComSourceInterfaces(typeof(IEventFor1C))]
    public class ClassForEvent1C
    {
        [ComVisible(false)]
        public delegate void Событие_Delgate();
        public delegate void СобытиеСПараметром_Delgate(object value);
        public object Объект;
        private SynchronizationContext Sc;

        public ClassForEvent1C(object Объект,String СобытиеОбъекта,bool ЕстьПараметр=false)
        {
            this.Объект = Объект;
            BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
            EventInfo ei = Объект.GetType().GetEvent(СобытиеОбъекта, bf);
              if (!ЕстьПараметр)
            ei.AddEventHandler(Объект, new System.Action(ВнешнееСобытие));
             else
            ei.AddEventHandler(Объект, new System.Action<object>(ВнешнееСобытиеСПараметром));

            SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
            Sc = SynchronizationContext.Current;

        }
        public event Событие_Delgate Событие;
        public event СобытиеСПараметром_Delgate СобытиеСПараметром;
       
        private void ВнешнееСобытие()
        {
          if (this.Событие != null) //Событие();
              Sc.Send(d => Событие(), null);

        
        }

        
        private void ВнешнееСобытиеСПараметром(object value)
        {
            if (this.СобытиеСПараметром != null) //Событие();
                Sc.Send(d => СобытиеСПараметром(AutoWrap.ОбернутьОбъект(value)), null);


        }

    }



Либо пишу ручками используя анонимные типы. И подписка
 void OnGetMessageImage(object value);




 wa.OnGetMessageImage += (mediaNode, from, id, fileName, fileSize, url, preview) =>
            {
                ОтослатьСобытиеСПараметром(OnGetMessageImage, new { mediaNode = mediaNode, from = from, id = id, fileName = fileName, fileSize = fileSize, url = url, preview = preview }, "OnGetMessageImage");
            };