Почему я не могу неявно бросить Делегата с Дополнительными методами?

Метод Promise.resolve () возвращает объект Promise, который разрешается с данным значением. Если значение является обещанием, это обещание возвращается; если значение является доступным (то есть имеет "then" method), возвращенное обещание будет «следовать» за этим доступным, принимая его возможное состояние; в противном случае возвращенное обещание будет выполнено со значением. Эта функция объединяет вложенные слои объектов, подобных обещанию (например, обещание, которое превращается в обещание, которое разрешается во что-то), в один слой.

См. здесь для получения дополнительной информации о Promise.resolve ().

Разница в выводе обоих ваших кодов связана с тем, что обработчики then вызываются асинхронно.

При использовании разрешенного обещания блок «then» будет активирован мгновенно, но его обработчики будут активированы асинхронно.

blockquote>

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

7
задан 12 February 2009 в 22:58
поделиться

3 ответа

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

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

Пример того, почему это повредилось бы:

class Test
{
    void M (void) // Fits Action delegate
    {
    }

    int M (int) // Fits Func<int,int> delegate
    {
        return 5;
    }

    void Test()
    {
        M.Exec(); // UHOH!!! Which Exec to resolve to ???
    }
}


public static class Extensions
{
    public static void Exec(this Action action) { }
    public static void Exec(this Func<int, int> func) { }
}

Как Вы видите, существует конфликт, но на самом деле, конфликта никогда не происходит, потому что C# даже не попытается найти расширение соответствия с группой метода.

Отметьте, как это не будет работать также:

class A
{
    public static implicit operator int (A a)
    {
        return 5;
    }

    void F()
    {
       A a = new A();
       a.Blah(); // Error! It won't implicitly try C.Blah()
    }
}

public static class C
{
    public static void Blah (int i)
    {
    }
}

C# не будет соответствовать A кому: C.Blah(int) потому что это потребовало бы неявного преобразования.

5
ответ дан 7 December 2019 в 05:30
поделиться

Как Coincoin говорит, он не собирается работать хорошо в C# из-за фанатичной любви к перегрузке метода. Единственное обходное решение, которое я видел, что люди используют, к методам Func и действию по созданию:

public Action Action(Action f) { return f; }
public Action<A> Action<A>(Action<A> f) { return f; }
...
public Func<A,B,C,D,E> Func(Func<A,B,C,D,E> f) { return f; }

Вы могли даже назвать их всех "F" для получения своего рода короткого синтаксиса:

F(BadMethod).NoExceptions();

Вы могли бы решить не определить эти методы в своем классе и поместить их в утилиту Funcs или что-то. Исказите его с F, и это не заканчивается слишком плохо:

F.F(BadMethod).NoException();

Но в целом это все еще сосет :(.

2
ответ дан 7 December 2019 в 05:30
поделиться

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

Эта информация хранится в блоке VS _ VERSION _ INFO исполняемого файла (см., например, этот вопрос ). Я не знаю ни одного инструмента, который извлекал бы эту информацию простым способом, даже на самой Windows.

Есть несколько способов получить эту информацию через Windows API (См. пример Perl здесь ), но я не вижу никакого подхода, который работает «с нуля», просто анализируя исполняемый файл.

Если вы немного покопаетесь, вы можете найти описание формата файла, которое объясняет, как прочитать информацию VS _ VERSION _ INFO из EXE-файла. Будьте готовы к большой работе, чтобы это сработало надежно.

Будьте готовы вложить много времени и сил, если вы хотите сделать это.

-121--2182939-

Первый запрос в 3:20 вызвал удержание некоторой памяти, но обратите внимание, что GC после второго запроса вернули большую часть. Также я думаю, что крупный ГК был выполнен только после второго запроса в 4:40.

Похоже, утечки нет. Моя теория состоит в том, что запрос в 3:20 заставил молодое поколение заполниться, и результирующая незначительная ГК продвинула некоторые объекты в старшее поколение. Следующий крупный GC, вызванный запросом в 4:40 очистил большинство из них.

Вы можете проверить это, используя профилировщик, чтобы пометить кучу, прежде чем выдать тот же запрос, что и в 3:20, принудив полный GC, а затем проверить, какие объекты задерживаются. Я не уверен, позволяет (1) вы пометить кучу и (2) форсировать полный GC, но он раньше делал это.

-121--4460417-

F # позволяет вам делать этот вид вещи очень естественно, обеспечивая гораздо лучшую систему вывода типа.

1
ответ дан 7 December 2019 в 05:30
поделиться
Другие вопросы по тегам:

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