Замените метод расширения в c # на & ldquo; using = & hellip; & rdquo; [Дубликат]

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

form_action_page.php

  & lt;? php post_async ("http: //localhost/projectname/testpage.php", "Keywordname = testValue");  //post_async("http://localhost/projectname/testpage.php "," Keywordname = testValue2 ");  //post_async("http://localhost/projectname/otherpage.php "," Keywordname = anyValue ");  // вызываем столько страниц, сколько вам понравится, все страницы будут выполняться сразу // независимо, не ожидая, что каждый ответ на страницу будет асинхронным.  // ваша вставка формы db или другой код идет здесь, что бы вы хотели, // код выше будет работать как фоновое задание, эта строка будет нажимать прямо перед ответом на вышеприведенные строки? & gt;  & lt;? php / * * Асинхронно выполняет асинхронную страницу PHP, поэтому текущая страница не должна ждать завершения ее работы.  * * / function post_async ($ url, $ params) {$ post_string = $ params;  $ частей = parse_url ($ URL);  $ fp = fsockopen ($ parts ['host'], isset ($ parts ['port'])? $ parts ['port']: 80, $ errno, $ errstr, 30);  $ out = "GET". $ parts ['path']. "? $ post_string". "HTTP / 1.1 \r \n"; // вы можете использовать POST вместо GET, если вам нравится $ out. = "Host:  ». $ части [ 'хозяин']. "\ г \n";  $ out. = "Content-Type: application / x-www-form-urlencoded \r \n";  $ out. = "Content-Length:" .strlen ($ post_string). "\r \n";  $ out. = "Соединение: Закрыть \r \n \r \n";  fwrite ($ fp, $ out);  fclose ($ FP);  }? & gt;   

testpage.php

  & lt ;?  echo $ _REQUEST ["Keywordname"]; // case1 Output & gt;  testValue // здесь выполняются фоновые операции, он не остановит главную страницу? & gt;   

PS: если вы хотите отправить параметры URL-адреса в виде цикла, выполните следующий ответ: https://stackoverflow.com/a/41225209/6295712

55
задан Stefanos Kargas 10 October 2013 в 17:15
поделиться

5 ответов

UPDATE: этот вопрос был предметом моего блога в декабре 2013 года . Спасибо за большой вопрос!


Вы можете сделать это, в некотором смысле. Но я должен начать с краткого обсуждения базового принципа проектирования разрешения перегрузки в C #. Разумеется, все разрешения перегрузки включают набор методов с тем же именем и выбор из этого набора уникального лучшего участника для вызова.

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

И поэтому мы пропустим список. Производные классы ближе, чем базовые классы. Внутренние классы ближе, чем внешние классы. Методы в иерархии классов ближе, чем методы расширения.

И теперь мы подошли к вашему вопросу. Близость метода расширения зависит от (1), сколько пробелов в пространстве имен мы должны были уйти? и (2) нашел ли мы метод расширения через using или был ли он правильным в пространстве имен? Поэтому вы можете повлиять на разрешение перегрузки, изменив в пространстве имен ваш статический класс расширения, чтобы поместить его в более близкое пространство имен на сайт вызова. Или вы можете изменить свои объявления using, чтобы поместить using пространства имен, которое содержит желаемый статический класс, ближе другого.

Например, если у вас есть

namespace FrobCo.Blorble
{
  using BazCo.TheirExtensionNamespace;
  using FrobCo.MyExtensionNamespace;
  ... some extension method call
}

, тогда это двусмысленно, что ближе. Если вы хотите расставить приоритеты по своему усмотрению, вы можете сделать это:

namespace FrobCo
{
  using BazCo.TheirExtensionNamespace;
  namespace Blorble
  {
    using FrobCo.MyExtensionNamespace;
    ... some extension method call
  }

И теперь, когда разрешение перегрузки идет для разрешения вызова метода расширения, классы в Blorple сначала идут, затем классы в FrobCo.MyExtensionNamespace, затем в классах FrobCo, а затем в классах BazCo.TheirExtensionNamespace.

Ясно, что

96
ответ дан bdukes 15 August 2018 в 17:22
поделиться
  • 1
    один вопрос здесь, как я могу скрыть свой метод класса над методом расширения, созданным для моего класса? например У класса Deer есть метод Run, и я хочу убедиться, что когда я использую Deer внутри «Mars», namespace (класс MarsLand), то я хочу убедиться, что метод Run, объявленный в методах расширения пространства имен Mars, будет вызван. Олень является частью пространства имен Земли. – Dhananjay 23 April 2012 в 13:51
  • 2
    @Dhananjay: применимый метод из иерархии классов always выигрывает по методу расширения. Если вам нужен метод расширения, который вызывается, назовите его как статический метод. – Eric Lippert 23 April 2012 в 15:35
  • 3
    Почему FrobCo.MyExtensionNamespace не ближе к любому классу в FrobCo.Blorble, чем BazCo.TheirExtensionNamespace? Мне кажется, что для BazCo-расширений вам нужно будет подняться на два уровня пространства имен, а затем вниз на два других, тогда как для FrobCo-расширений вам нужно будет только подняться на один уровень пространства имен. Поэтому для меня расширения FrobCo кажутся ближе. – Virtlink 18 October 2012 в 15:38
  • 4
    Невероятный. Я узнал 3 или 4 вещи за несколько минут, которые потребовались, чтобы прочитать этот ответ. – Michael 6 May 2015 в 14:27

Методы расширения нельзя переопределить, поскольку они не являются методами экземпляра, и они не являются виртуальными.

Компилятор будет жаловаться, если вы импортируете оба класса метода расширения через пространство имен, поскольку он не будет знать, какой метод вызывать:

Вызов неоднозначен между следующими методами или свойствами : ...

Единственный способ этого - вызвать метод расширения с использованием стандартного синтаксиса статического метода. Поэтому вместо этого:

a.Foo();

вам нужно будет сделать это:

YourExtensionMethodClass.Foo(a);
27
ответ дан BartoszKP 15 August 2018 в 17:22
поделиться
  • 1
    Ну, как отмечает Эрик, он не импортирует два разных подходящих метода расширения, они импортируют их на одном уровне вложенности. и я уверен, что он говорит о переопределении поведения одного метода с поведением другого, а не о полиморфном поведении – Rune FS 20 September 2009 в 16:46

Методы расширения - это в основном просто статические методы, поэтому я не знаю, как их переопределить, но если вы просто поместите их в другое пространство имен, вы можете позвонить вместо них, вместо того, который хотите заменить.

Но Мэтт Манела рассказывает о том, как методы экземпляра имеют приоритет над методами расширения: http://social.msdn.microsoft.com/forums/en-US/csharplanguage/thread/e42f1511-39e7-4fed-9e56- 0cc19c00d33d

Для получения дополнительных идей о методах расширения вы можете посмотреть http://gen5.info/q/2008/07/03/extension-methods-nulls-namespaces-and -precedence-in-c /

Редактирование: я забыл о проблеме двусмысленности, поэтому лучше всего попытаться не включать методы расширения, которые вы хотите заменить. Таким образом, вам может понадобиться не использовать директиву «using», а просто поместить в полное имя пакета некоторые классы, и это может решить проблему.

4
ответ дан James Black 15 August 2018 в 17:22
поделиться

В дополнение к существующим ответам вы также можете «переопределить» методы расширения, изменив сигнатуру метода:

1.) Используйте более конкретный тип

Это может быть только конечно, если целевой тип более конкретный, чем тип существующего метода расширения. Кроме того, это может потребоваться для всех применимых типов.

// "override" the default Linq method by using a more specific type
public static bool Any<TSource>(this List<TSource> source)
{
    return Enumerable.Any(source);
}

// this will call YOUR extension method
new List<T>().Any();

2.) Добавить фиктивный параметр

Не так красиво. Кроме того, для этого потребуется изменить существующие вызовы, чтобы включить фиктивный аргумент.

// this will be called instead of the default Linq method when "override" is specified
public static bool Any<TSource>(this IEnumerable<TSource> source, bool @override = true)
{
    return source.Any();
}

// this will call YOUR extension method
new List<T>().Any(true);
0
ответ дан marsze 15 August 2018 в 17:22
поделиться

Исходя из предпосылки Eric (и того факта, что код представления отображается в пространстве имен ASP), вы должны уметь переопределять его таким образом (по крайней мере, это работает для меня в ASP.NET MVC4.0 Razor

using System.Web.Mvc;

namespace ASP {
  public static class InputExtensionsOverride {
    public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name) {
      TagBuilder tagBuilder = new TagBuilder("input");
      tagBuilder.Attributes.Add("type", "text");
      tagBuilder.Attributes.Add("name", name);
      tagBuilder.Attributes.Add("crazy-override", "true");
      return new MvcHtmlString(tagBuilder.ToString(TagRenderMode.Normal));
    }
  }
}

Обратите внимание, что пространство имен должно быть «ASP».

3
ответ дан Ondrej Svejdar 15 August 2018 в 17:22
поделиться
Другие вопросы по тегам:

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