ECMAScript 6 имеет «генераторы», которые позволяют вам легко программировать в асинхронном стиле.
function* myGenerator() {
const callback = yield;
let [response] = yield $.ajax("https://stackoverflow.com", {complete: callback});
console.log("response is:", response);
// examples of other things you can do
yield setTimeout(callback, 1000);
console.log("it delayed for 1000ms");
while (response.statusText === "error") {
[response] = yield* anotherGenerator();
}
}
Для запуска вышеуказанного кода вы делаете это:
const gen = myGenerator(); // Create generator
gen.next(); // Start it
gen.next((...args) => gen.next([...args])); // Set its callback function
Если вам нужно настроить таргетинг на браузеры, которые не поддерживают ES6, вы можете запустить код через Babel или short-compiler для генерации ECMAScript 5.
Обратный вызов ...args
завернут в массив и разрушен, когда вы их читаете так что шаблон может справиться с обратными вызовами, которые имеют несколько аргументов. Например, с узлом fs :
const [err, data] = yield fs.readFile(filePath, "utf-8", callback);
Невозможно. Ничто не указывает пространство имен «корень». По умолчанию пространство имен в параметрах - это визуальная студийная вещь, а не вещь .net
Я только что создал пустой внутренний класс Root и поместил его в корневой каталог проекта (предполагая, что это ваше корневое пространство имен). Затем я использую это везде, где мне нужно корневое пространство имен:
typeof(Root).Namespace;
Конечно, у меня есть неиспользуемый файл, но он чист.
Get Types предоставляет вам список объектов Type , определенных в сборке. Этот объект имеет свойство пространства имен. Помните, что сборка может иметь несколько пространств имен.
Вопрос, который у меня был у меня, был: «Если я вызову библиотечный код N методов глубоко и хочу пространство имен проекта - например, приложение MVC, которое действительно работает, - как это получить?»
Немного взломанный, но вы можете просто захватить стек и трафик:
public static string GetRootNamespace()
{
StackTrace stackTrace = new StackTrace();
StackFrame[] stackFrames = stackTrace.GetFrames();
string ns = null;
foreach(var frame in stackFrames)
{
string _ns = frame.GetMethod().DeclaringType.Namespace;
int indexPeriod = _ns.IndexOf('.');
string rootNs = _ns;
if (indexPeriod > 0)
rootNs = _ns.Substring(0, indexPeriod);
if (rootNs == "System")
break;
ns = _ns;
}
return ns;
}
Все это делается, это получение stacktrace, запуск методов из последнего вызова root и фильтрация для System , Когда он найдет системный вызов, он знает, что он зашел слишком далеко и возвращает вам пространство имен непосредственно над ним. Если вы используете модульный тест, приложение MVC или службу, системный контейнер будет сидеть на 1 уровень глубже корневого пространства имен вашего проекта, поэтому voila.
В некоторых сценариях, где Системный код является промежуточным (например, System.Task) по трассировке, который возвращает неверный ответ. Моя цель состояла в том, чтобы взять, например, некоторый код запуска и позволить ему легко найти класс или контроллер или что-то еще в корневом пространстве имен, даже если код, выполняющий работу, выйдет в библиотеке. Это выполняет эту задачу.
Я уверен, что это может быть улучшено. Я уверен, что этот хакерский способ сделать что-то может быть улучшен во многих отношениях, и улучшения приветствуются.
Я столкнулся с этой дилеммой много раз, когда хочу загрузить ресурс из текущей сборки по его манифестному потоку ресурсов.
Дело в том, что если вы вставляете файл в качестве ресурса в свой сборка с использованием Visual Studio его имя ресурса будет выведено из пространства имен по умолчанию сборки, как определено в проекте Visual Studio.
Лучшее решение, которое я придумал (чтобы избежать жесткого кодирования пространства имен по умолчанию как строка где-то) заключается в том, чтобы просто гарантировать, что ваш код загрузки ресурса ВСЕГДА происходит изнутри класса, который также находится в пространстве имен по умолчанию, а затем может использоваться следующий подход, основанный на принципе общего доступа.
В этом примере загружается встроенный схема
XmlSchema mySchema;
string resourceName = "MyEmbeddedSchema.xsd";
string resourcesFolderName = "Serialisation";
string manifestResourceName = string.Format("{0}.{1}.{2}",
this.GetType().Namespace, resourcesFolderName, resourceName);
using (Stream schemaStream = currentAssembly.GetManifestResourceStream(manifestResourceName))
mySchema = XmlSchema.Read(schemaStream, errorHandler);
См. также: Как получить пространство имен сборки?
Редактировать: Также был замечен очень подробный ответ на вопрос I [ m отвечает на http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/3a469f5d-8f55-4b25-ac25-4778f260bb7e
Другое редактирование в случае, если люди с одинаковым вопросом приходят в себя: Отличная идея решить вопрос загрузки ресурсов здесь: Как получить пространство имен по умолчанию проекта csproj (VS 2008)
Фактически есть косвенный способ получить его, перечисляя имена манифестных ресурсов сборки. Имя, которое вы хотите, заканчивается той частью, которую вы знаете.
Вместо повторения кода здесь, см. get Имя пространства имен по умолчанию для метода Assembly.GetManifestResourceStream ()
Здесь, как довольно простой способ получить корневое пространство имен для проекта веб-сайта.
''' <summary>
''' Returns the namespace of the currently running website
''' </summary>
Public Function GetWebsiteRootNamespace() As String
For Each Asm In AppDomain.CurrentDomain.GetAssemblies()
If Asm Is Nothing OrElse Asm.IsDynamic Then Continue For
For Each Typ In Asm.GetTypes
If Typ Is Nothing OrElse Typ.Name Is Nothing Then Continue For
If Typ.Name = "MyProject" Then Return Typ.Namespace.Split("."c)(0)
Next
Next
Return Nothing
End Function
Это просто проверяет все загруженные сборки для типа «MyProject» и возвращает корневое пространство имен для этого типа , Это полезно для ведения журнала, когда у вас есть несколько веб-проектов в одном решении, использующем систему журналов. Надеюсь, это кому-то поможет.
GetType(frm).Namespace
frm
- это форма запуска
В данной сборке может быть любое количество пространств имен, и ничто не требует, чтобы все они начинались с общего корня. Лучшее, что вы могли бы сделать, это отразить все типы сборки и создать список уникальных пространств имен, содержащихся в нем.
Добавляя ко всем остальным ответам здесь, надеюсь, без повторения информации, вот как я решил это использовать Linq. Моя ситуация похожа на ответ Лизы.
Мое решение имеет следующие оговорки:
Dim baseNamespace = String.Join("."c,
Me.GetType().Assembly.ManifestModule.GetTypes().
Select(Function(type As Type)
Return type.Namespace.Split("."c)
End Function
).
Aggregate(Function(seed As String(), splitNamespace As String())
Return seed.Intersect(splitNamespace).ToArray()
End Function
)
)
Пространства имен не имеют ничего общего с сборками - любое сопоставление между пространством имен и классами в сборке происходит исключительно из-за соглашения об именах (или совпадения).
Я использую typeof(App).Namespace
в своем приложении WPF. Класс App является обязательным для любого приложения WPF и расположен в корне.
Ассембли не обязательно имеют корневое пространство имен. Пространства имен и сборки являются ортогональными.
Вместо этого вы можете найти тип внутри этой сборки, а затем выяснить, каково его пространство имен.
Вы должны быть способны для этого, используя элемент GetExportedTypes (), а затем используя свойство Namespace из одного из возвращаемых дескрипторов типа.
Опять же, нет гарантий, что все типы находятся в одном и том же пространстве имен (или даже в том же Иерархия пространства имен).