pointers to members in C#
От: Nekto_2004  
Дата: 12.07.04 16:59
Оценка:
Привет всем!
pointers to members — как это сделать на С#-е?

Я хочу написать как в С++:
class Window
{
public:
.............
   bool SetCaption( const char *szTitle ); // Set window caption.
..................
};
......................

bool (Window::*pfnwSC)( const char * ) = &Window::SetCaption;

Window wMainWindow;
const char* szCaptionBase = "la-la-bla-bla" ;
............
(pwChildWindow->*pfnwSC)( szCaptionBase );

Я так понял в шарпе поддержки pointer to members нет ( ), а как обойти?
Заранее спасибо!
Re: pointers to members in C#
От: mikа Stock#
Дата: 12.07.04 17:10
Оценка: 21 (1)
Здравствуйте, Nekto_2004, Вы писали:

Delegate. И member — это не только метод.
Re[2]: pointers to members in C#
От: Nekto_2004  
Дата: 13.07.04 07:41
Оценка:
Здравствуйте, mikа, Вы писали:

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


M>Delegate. И member — это не только метод.


[msdn]
The declaration of a delegate type establishes a contract that specifies the signature of one or more methods. A delegate is an instance of a delegate type, and references one or more of the following:

A target object that is not a null reference (Nothing in Visual Basic) and an instance method of the target object
A static method
.... When a delegate references an instance method, the delegate stores a reference to the method's entry point and a reference to an object, called the target, which is the class instance that the method is invoked on. The target of an instance method cannot be a null reference (Nothing). When a delegate references a static method, the delegate stores a reference to the method's entry point. The target of a static method is a null reference (Nothing).
[/msdn]

А если мне не известен этот target object? А известен только member, который я буду вызывать. А target object будет известен позже. Что делать? Короче, хочу как в C++, иметь pointer to member(я понимаю, что это не только метод) — далее хочу пробежаться по какой-то коллекции конкретных instancов и вызвать этот pointer to member. Как это сделать с помощью делегатов, я не знаю. Плиз, подскажите, как. Спасибо.
Re[3]: pointers to members in C#
От: mikа Stock#
Дата: 13.07.04 07:45
Оценка:
Здравствуйте, Nekto_2004, Вы писали:

public class SomeClass
{
  public SomeClass()
  {
     // Вот тут у тебя ссылк на метода.
     EventHandler handler = new EventHandler(OnEventHandler);

     // Вот тут мы вызываем методы.
     handler(this, EventArgs.Empty);
  }

  private void OnEventHandler(object sender, EventArgs e)
  {
    // Это наш метод, на которые получаем ссылку.
  }
}
Re[3]: pointers to members in C#
От: TK Лес кывт.рф
Дата: 13.07.04 07:56
Оценка: 2 (1)
Hello, "Nekto_2004"

> А если мне не известен этот target object? А известен только member, который я буду вызывать. А target object будет известен позже. Что делать? Короче, хочу как в C++, иметь pointer to member(я понимаю, что это не только метод) — далее хочу пробежаться по какой-то коллекции конкретных instancов и вызвать этот pointer to member. Как это сделать с помощью делегатов, я не знаю. Плиз, подскажите, как. Спасибо.


Тут нужно учитывать, что делегат это не прямая калька с указателя на функцию (например если брать delphi или c++ builder, то делегат это близкий аналог указателя на метод с модификатором __closure). Если-же нужно вызвать определенный метод, для произвольного набора экземпляров, то можно хранить использовать Delegate.CreateDelegate для создания делегата привязанного к конкретному экземпляру и вызов через него метода. Либо, воспользоваться reflection, хранить в качестве указателя на метод объект MethodInfo и для вызова метода над конкретным экземпляром использовать MethodInfo.Invoke
Posted via RSDN NNTP Server 1.9 alpha
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[4]: pointers to members in C#
От: OldDino Россия  
Дата: 13.07.04 08:30
Оценка:
Здравствуйте, TK, Вы писали:

TK>Hello, "Nekto_2004"


>> А если мне не известен этот target object? А известен только member, который я буду вызывать. А target object будет известен позже. Что делать? Короче, хочу как в C++, иметь pointer to member(я понимаю, что это не только метод) — далее хочу пробежаться по какой-то коллекции конкретных instancов и вызвать этот pointer to member. Как это сделать с помощью делегатов, я не знаю. Плиз, подскажите, как. Спасибо.


TK>Тут нужно учитывать, что делегат это не прямая калька с указателя на функцию (например если брать delphi или c++ builder, то делегат это близкий аналог указателя на метод с модификатором __closure). Если-же нужно вызвать определенный метод, для произвольного набора экземпляров, то можно хранить использовать Delegate.CreateDelegate для создания делегата привязанного к конкретному экземпляру и вызов через него метода. Либо, воспользоваться reflection, хранить в качестве указателя на метод объект MethodInfo и для вызова метода над конкретным экземпляром использовать MethodInfo.Invoke


Тимофей, это у меня ещё один вопрос вызвало. Допустим, я считал файл в память или сделал ММФ, неважно. В С++ я создаю указатель на структуру, который затем приравниваю указателю на конкретный участок файла. В результате дополнительных структур я фактически не создаю, обхожусь только указателями. Как такой же фокус провернуть в Шарпе?

С уважением,

OldDino
Re[5]: pointers to members in C#
От: TK Лес кывт.рф
Дата: 13.07.04 08:51
Оценка:
Hello, "OldDino"
>
> Тимофей, это у меня ещё один вопрос вызвало. Допустим, я считал файл в память или сделал ММФ, неважно. В С++ я создаю указатель на структуру, который затем приравниваю указателю на конкретный участок файла. В результате дополнительных структур я фактически не создаю, обхожусь только указателями. Как такой же фокус провернуть в Шарпе?
>

Если нужен именно такой фокус, то надо объявить в шарпе все нужные структуры, а дальше работать как в С++ — с использованием указателей (нужно будет разрешить unsafe). С другой стороны, если unsafe не нравится, но и хочется работать со структурами лежащими по произвольному адресу, то зная, что использование ref при передаче структуры означает ее передачу по указателю можно извернуться примерно так:

using System;
using System.Reflection;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
public struct MyValues
{
    public int val1;
    public int val2;
}

public delegate void MyValuesHandler(ref MyValues vals);
public delegate void MyValuesHandlerStub(IntPtr vals);

[StructLayout(LayoutKind.Explicit)]
public struct DelegeateMixer
{
    [FieldOffset(0)]
    public MyValuesHandler Handler;
    
    [FieldOffset(0)]
    public MyValuesHandlerStub HandlerStub;
}

class Program
{
    static void Main(string[] args)
    {
        MyValues vals = new MyValues();
        vals.val1 = 1234;
        vals.val2 = 4321;
        
        DelegeateMixer mixer = new DelegeateMixer();
        mixer.Handler = new MyValuesHandler(MyValuesHandler);

        IntPtr unmanagedData =  Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MyValues)));
        
        Marshal.StructureToPtr(vals, unmanagedData, false);

        // вызываем MyValuesHandler(ref MyValues vals) передав в качестве параметра 
        // указатель на "произвольный" участок памяти
        mixer.HandlerStub(unmanagedData);

        Marshal.FreeHGlobal(unmanagedData);
    }

    public static void MyValuesHandler(ref MyValues vals)
    {
        Console.WriteLine("Value1: {0}", vals.val1);
        Console.WriteLine("Value2: {0}", vals.val2);
    }
}
Posted via RSDN NNTP Server 1.9 alpha
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[6]: pointers to members in C#
От: OldDino Россия  
Дата: 13.07.04 08:53
Оценка:
Здравствуйте, TK, Вы писали:


TK>Если нужен именно такой фокус, то надо объявить в шарпе все нужные структуры, а дальше работать как в С++ — с использованием указателей (нужно будет разрешить unsafe). С другой стороны, если unsafe не нравится, но и хочется работать со структурами лежащими по произвольному адресу, то зная, что использование ref при передаче структуры означает ее передачу по указателю можно извернуться примерно так:


Благодарю. Разберусь подробнее дома, а о результатах — сообщу.

С уважением,

OldDino
Re[4]: pointers to members in C#
От: Nekto_2004  
Дата: 13.07.04 09:00
Оценка:
Здравствуйте, TK, Вы писали:

TK>Hello, "Nekto_2004"


>> А если мне не известен этот target object? А известен только member, который я буду вызывать. А target object будет известен позже. Что делать? Короче, хочу как в C++, иметь pointer to member(я понимаю, что это не только метод) — далее хочу пробежаться по какой-то коллекции конкретных instancов и вызвать этот pointer to member. Как это сделать с помощью делегатов, я не знаю. Плиз, подскажите, как. Спасибо.


TK>Тут нужно учитывать, что делегат это не прямая калька с указателя на функцию (например если брать delphi или c++ builder, то делегат это близкий аналог указателя на метод с модификатором __closure). Если-же нужно вызвать определенный метод, для произвольного набора экземпляров, то можно хранить использовать Delegate.CreateDelegate для создания делегата привязанного к конкретному экземпляру и вызов через него метода. Либо, воспользоваться reflection, хранить в качестве указателя на метод объект MethodInfo и для вызова метода над конкретным экземпляром использовать MethodInfo.Invoke


Угу, похоже придется так. Я так думаю с точки зрения эффективности предпочтительней CreateDelegate. Вроде мы выясняли, решили что он работает не через рефлекшн. Второй метод более тормозной. Хотя пока не поэкспериментриуешь, нихрена не знаешь.
Re[5]: pointers to members in C#
От: TK Лес кывт.рф
Дата: 13.07.04 09:03
Оценка:
Hello, "Nekto_2004"
>
> Угу, похоже придется так. Я так думаю с точки зрения эффективности предпочтительней CreateDelegate. Вроде мы выясняли, решили что он работает не через рефлекшн. Второй метод более тормозной. Хотя пока не поэкспериментриуешь, нихрена не знаешь.

Только учти, что делегат придется как минимум создать так что тормоз на тормоз — еще не известно, кто победит в конкретной ситуации...
Posted via RSDN NNTP Server 1.9 alpha
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.