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

Сообщение Re[4]: Приоритет вызова перегруженных методов от 07.06.2016 11:27

Изменено 07.06.2016 12:51 Serginio1

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

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


S>> InvokeMember брал на себя поиск нужного метода и передачу параметров params.

S>>И соответственно встал вопрос как искать подходящий метод.

S>Для начала лучше перетащить разруливание перегрузок в managed-код. Дальше проще и зависит от задачи.


S>Подобрать перегрузку, зная типы аргументов? type.GetMethod("name", bindingFlags, argTypes) или как-то так.


S>Известны только значения? Пишем вызов любого метода через dynamic, с помошью декомпилятора смотрим что за код генерится под капотом, повторяем вручную. Ключевые слова для поиска — CallSite<T>, CallSiteBinder.


S>Первое попавшееся: https://habrahabr.ru/post/144330/


Я хочу сделать по аналогии с Использование сборок .NET в 1С 7.x b 8.x.

То есть использование любых сборок из Натива. Например http://ru.stackoverflow.com/questions/532477/%d0%9f%d1%80%d0%be%d0%b2%d0%b5%d1%80%d0%ba%d0%b0-%d0%bf%d0%be%d0%b4%d0%bf%d0%b8%d1%81%d0%b8-%d0%ad%d0%a6%d0%9f-%d0%b2-%d1%84%d0%b0%d0%b9%d0%bb%d0%b5-online-%d0%bf%d1%80%d0%be%d0%b2%d0%b5%d1%80%d0%ba%d0%b0-%d1%81%d0%b5%d1%80%d1%82%d0%b8%d1%84%d0%b8%d0%ba%d0%b0%d1%82%d0%b0-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-c-%d1%87%d0%b5%d1%80%d0%b5%d0%b7-%d0%b1%d0%b8%d0%b1

Это все прекрасно работает в Win через COM и InvokeMember. Но есть желание перенести это все на Линукс.
Соответственно я не знаю, что и как будет вызываться, но динамически я должен найти самый подходящий перегруженный метод.

Например есть две функции

void Метод(int парам, string str)
 void Метод(int парам, object str)

При вызове Метод(1,null) какой метод выбрать?

С параметрами массивами
void Метод(int парам, params object[] str)
void Метод(int парам,int пара2, object str)

Метод(1,1,6)
Re[4]: Приоритет вызова перегруженных методов
Здравствуйте, Sinix, Вы писали:

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


S>> InvokeMember брал на себя поиск нужного метода и передачу параметров params.

S>>И соответственно встал вопрос как искать подходящий метод.

S>Для начала лучше перетащить разруливание перегрузок в managed-код. Дальше проще и зависит от задачи.


S>Подобрать перегрузку, зная типы аргументов? type.GetMethod("name", bindingFlags, argTypes) или как-то так.


S>Известны только значения? Пишем вызов любого метода через dynamic, с помошью декомпилятора смотрим что за код генерится под капотом, повторяем вручную. Ключевые слова для поиска — CallSite<T>, CallSiteBinder.


S>Первое попавшееся: https://habrahabr.ru/post/144330/


Я хочу сделать по аналогии с Использование сборок .NET в 1С 7.x b 8.x.

То есть использование любых сборок из Натива. Например http://ru.stackoverflow.com/questions/532477/%d0%9f%d1%80%d0%be%d0%b2%d0%b5%d1%80%d0%ba%d0%b0-%d0%bf%d0%be%d0%b4%d0%bf%d0%b8%d1%81%d0%b8-%d0%ad%d0%a6%d0%9f-%d0%b2-%d1%84%d0%b0%d0%b9%d0%bb%d0%b5-online-%d0%bf%d1%80%d0%be%d0%b2%d0%b5%d1%80%d0%ba%d0%b0-%d1%81%d0%b5%d1%80%d1%82%d0%b8%d1%84%d0%b8%d0%ba%d0%b0%d1%82%d0%b0-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-c-%d1%87%d0%b5%d1%80%d0%b5%d0%b7-%d0%b1%d0%b8%d0%b1

Это все прекрасно работает в Win через COM и InvokeMember. Но есть желание перенести это все на Линукс.
Соответственно я не знаю, что и как будет вызываться, но динамически я должен найти самый подходящий перегруженный метод.

Например есть две функции

void Метод(int парам, string str)
 void Метод(int парам, object str)

При вызове Метод(1,null) какой метод выбрать?

С параметрами массивами
void Метод(int парам, params object[] str)
void Метод(int парам,int пара2, object str)

Метод(1,1,6)

Кстати в Core .Net много отличий. Например во взрослом
public abstract object[] GetCustomAttributes(
    Type attributeType,
    bool inherit
)


То в Core все через расширения
public static IEnumerable<Attribute> GetCustomAttributes(this ParameterInfo element, Type attributeType, bool inherit);


Так на просторах нашел


public static object call(MethodInfo Method, object Target, params object[] input)
        {

   
            ParameterInfo[] parameters = Method.GetParameters();
            bool hasParams = false;
            if (parameters.Length > 0)
                hasParams = parameters[parameters.Length - 1].GetCustomAttributes(typeof(ParamArrayAttribute), false).GetEnumerator().MoveNext();

            if (hasParams)
            {
                int lastParamPosition = parameters.Length - 1;

                object[] realParams = new object[parameters.Length];
                for (int i = 0; i < lastParamPosition; i++)
                    realParams[i] = input[i];

                Type paramsType = parameters[lastParamPosition].ParameterType.GetElementType();
                Array extra = Array.CreateInstance(paramsType, input.Length - lastParamPosition);
                for (int i = 0; i < extra.Length; i++)
                    extra.SetValue(input[i + lastParamPosition], i);

                realParams[lastParamPosition] = extra;

                input = realParams;
            }

            return Method.Invoke(Target, input);
        }


Но нужно смотреть на Out и Ref параметры.