Почему делегаты C # ограничены, чтобы принимать только 16 параметров.? [Дубликат]

Другое решение состоит в том, чтобы выполнить код через последовательный исполнитель nsynjs .

Если базовая функция многозначна

nsynjs будет последовательно оценивать все обещания и ставить обещания результат в свойство data:

function synchronousCode() {

    var getURL = function(url) {
        return window.fetch(url).data.text().data;
    };
    
    var url = 'https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js';
    console.log('received bytes:',getURL(url).length);
    
};

nsynjs.run(synchronousCode,{},function(){
    console.log('synchronousCode done');
});

Если базовая функция не обещает

Шаг 1. Wrap с обратным вызовом в оболочку, совместимую с nsynjs (если у нее есть обещанная версия, вы можете пропустить этот тест):

var ajaxGet = function (ctx,url) {
    var res = {};
    var ex;
    $.ajax(url)
    .done(function (data) {
        res.data = data;
    })
    .fail(function(e) {
        ex = e;
    })
    .always(function() {
        ctx.resume(ex);
    });
    return res;
};
ajaxGet.nsynjsHasCallback = true;

Шаг 2. Вставить синхронную логику в функцию:

function process() {
    console.log('got data:', ajaxGet(nsynjsCtx, "data/file1.json").data);
}

Шаг 3. Выполнить функцию синхронно через nnsynjs:

nsynjs.run(process,this,function () {
    console.log("synchronous function finished");
});

Nsynjs будет оценивать все операторы и выражения шаг за шагом, приостанавливая выполнение в случае, если результат некоторой медленной функции не готов.

Дополнительные примеры здесь: https://github.com/amaksr/nsynjs/tree/master/examples

19
задан Kirill Polishchuk 29 December 2014 в 22:47
поделиться

6 ответов

Вы надеетесь на что-то вроде аргументов вариационного типа , которых нет в C #. C # требует, чтобы арность родовых типов была исправлена, поэтому отвратительное распространение типов Func, Action и Tuple.

Если вы используете язык, эта функция была добавлена ​​в C ++ 11, но вы, вероятно, должны просто использовать jQuery. : -)

17
ответ дан Daniel 26 August 2018 в 12:15
поделиться

Я думаю, что я понимаю, что вы можете делать с JavaScript и функциями (аргументами), преатитесь аккуратно, но он также не статически типизирован.

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

Of Конечно, это похоже на C #:

Func<A1,Func<A2,Func<A3,...<Func<An,Result>>...> 
  x1 =>
    (x2 => 
      (x3 => 
        ... 
          (xn => 
              { /*return soomething */ }
  ))...);

, но это то, что F # для;) и, конечно же, вы никогда не должны делать функцию с более чем несколькими аргументами (путь ниже 16!) во всяком случае.

5
ответ дан Carsten 26 August 2018 в 12:15
поделиться

Why is there a limit anyway?

Существует мнение, что функция, вероятно, не должна содержать более трех аргументов. Если этого больше, становится все труднее понять. Конечно, это не может быть причиной того, что именно так в C #, но это ограничение, возможно, не так уж плохо.

Я бы сказал, что даже этот предел 16 слишком много и уже обнадеживает плохой дизайн.

1
ответ дан driushkin 26 August 2018 в 12:15
поделиться

Вы можете просто определить любого делегата, который вам нужен. Таким образом, Func с 20 параметрами будет определен следующим образом:

public delegate R Func<
    P0, P1, P2, P3, P4, P5, P6, P7, P8, P9,
    P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, R>(
        P0 p0, P1 p1, P2 p2, P3 p3, P4 p4,
        P5 p5, P6 p6, P7 p7, P8 p8, P9 p9,
        P10 p10, P11 p11, P12 p12, P13 p13, P14 p14,
        P15 p15, P16 p16, P17 p17, P18 p18, P19 p19);

Затем вы можете использовать его следующим образом:

Func<
        int, int, int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int, int, int, int> f = (
            p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
            p11, p12, p13, p14, p15, p16, p17, p18, p19) =>
                p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10
                    + p11 + p12 + p13 + p14 + p15 + p16 + p17 + p18 + p19;

var r = f(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);

C # также позволяет использовать синтаксис лямбда на любой делегат, поэтому вы также можете это сделать:

public delegate R ArrayFunc<P, R>(params P[] parameters);

И затем используйте его так:

ArrayFunc<int, int> af = ps => ps.Sum();

var ar = af(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);

Это очень гибкая и мощная функция языка.

14
ответ дан Enigmativity 26 August 2018 в 12:15
поделиться

Вы можете создать свой собственный делегат с более чем 16 аргументами. Или вы можете использовать Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> (или любую другую структуру данных) как параметр.

1
ответ дан Kirill Polishchuk 26 August 2018 в 12:15
поделиться

Делегаты System.Func, вероятно, существуют благодаря команде BCL .. кто понял, включая конечное число предопределенных общих делегатов, было бы удобно (и даже потребовалось бы для множества ситуаций).

что вы говорите .. то есть неограниченное количество общих параметров для делегата Func потребует изменения языка .. ответственность будет лежать как с командами c #, так и с vb.net (и, вероятно, с другими), чтобы изменить язык, чтобы это разрешить.

Возможно, в какой-то момент, если преимущество этой функции перевешивает стоимость предопределения нескольких делегатов Func, и это более важно, чем другие изменения языка (и что это не прерывное изменение) релевантные команды моя реализация неограниченных общих параметров .. может быть не на какое-то время, хотя!

1
ответ дан Martin Booth 26 August 2018 в 12:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: