Ну, первое, что нужно отметить, это то, что на самом деле лямбда-выражения могут быть рекурсивными. Нет, честно! Это нелегко сделать, и , конечно, нелегко читать - черт, у большинства поставщиков LINQ (кроме LINQ-to-Objects, что намного проще) будет кашель, просто глядя на него ... но это возможно . См. Здесь для полной, кровавой детали (предупреждение - боль в мозге, скорее всего).
Однако !! Это, вероятно, не очень поможет ... для практического подхода, я бы посмотрел, как XElement
и т. Д. Это делает ... обратите внимание, что вы можете удалить часть рекурсии, используя Queue
или Stack
:
using System;
using System.Collections.Generic;
static class Program {
static void Main() {
Node a = new Node("a"), b = new Node("b") { Children = {a}},
c = new Node("c") { Children = {b}};
foreach (Node node in c.Descendents()) {
Console.WriteLine(node.Name);
}
}
}
class Node { // very simplified; no sanity checking etc
public string Name { get; private set; }
public List Children { get; private set; }
public Node(string name) {
Name = name;
Children = new List();
}
}
static class NodeExtensions {
public static IEnumerable Descendents(this Node node) {
if (node == null) throw new ArgumentNullException("node");
if(node.Children.Count > 0) {
foreach (Node child in node.Children) {
yield return child;
foreach (Node desc in Descendents(child)) {
yield return desc;
}
}
}
}
}
Альтернативой было бы написать что-то вроде SelectDeep
(чтобы имитировать SelectMany
для отдельных уровней):
public static class EnumerableExtensions
{
public static IEnumerable SelectDeep(
this IEnumerable source, Func> selector)
{
foreach (T item in source)
{
yield return item;
foreach (T subItem in SelectDeep(selector(item),selector))
{
yield return subItem;
}
}
}
}
public static class NodeExtensions
{
public static IEnumerable Descendents(this Node node)
{
if (node == null) throw new ArgumentNullException("node");
return node.Children.SelectDeep(n => n.Children);
}
}
Опять же, я не оптимизировал это чтобы избежать рекурсии, но это можно сделать достаточно легко.
Flex компилирует внешний файл CSS при публикации проекта.
Существует способ загрузить CSS во время выполнения с помощью Flex; это можно сделать, скомпилировав файлы CSS в файлы SWF и загрузив их во время выполнения с помощью StyleManager.loadStyleDeclarations
.
Дополнительную информацию см. В LiveDocs в таблицах стилей во время выполнения .
Flex - это не то, с чем я имел дело, но я провел небольшое исследование. Похоже, что код для вызова удаленной таблицы стилей выглядит следующим образом:
<mx:Style source="com/example/assets/stylesheet.css" />
Flex Quick Start: Создание простого пользовательского интерфейса: Стилизация ваших компонентов говорит следующее:
Примечание: вам следует попытаться ограничить количество таблиц стилей, используемых в приложение и установите таблицу стилей только в документе верхнего уровня в заявление (документ, содержит тег). Если вы устанавливаете таблицу стилей в дочернем документ, неожиданные результаты могут
Из этого следует, что использование нескольких таблиц стилей на самом деле невозможно. Похоже, что вы хотите организовать свои таблицы стилей, посмотрите Организация ваших таблиц стилей и Архитектура CSS для некоторых идей для подходов. Похоже, у вас есть классы и базовые теги, но спецификации таблицы стилей W3C отличаются от спецификации таблицы стилей Flex.
Как разработчик, не использующий Flex, пространства имен выглядят интересным как способ организации пространств имен: Как использовать новый синтаксис CSS в Flex 4 .
Некоторые соглашения, которые мы используем при организации таблиц стилей:
main.css
, которая содержит все данные для оформления базового приложения. fonts.css
для хранения всех шрифтов в основном приложении, потому что они могут быть довольно беспорядочными. Таблица стилей main.css включается в основной swf через тег
. Мы загружаем наше приложение как можно меньше, а когда все загружено, если нам нужно немедленно показать какой-то текст (иногда у нас просто играет видео, если это рекламный сайт), мы делаем fade/tween в основных элементах и загружаем fonts.css через StyleManager.loadStyleDeclarations
во время выполнения.
admin.css
, которую мы загружаем во время выполнения, потому что основному приложению она не нужна. Нам не нужно делить CSS на части, потому что мы обычно создаем целый набор скинов в теме, поэтому таблица стилей просто применяет эти скины к компонентам и является довольно компактной (при использовании Flex 4). Я не разделяю таблицы стилей на более мелкие (например, "pages.css", "comments.css", "popups.css", или даже "controls.css" и т.д.), потому что это было бы излишеством и слишком большой нагрузкой на управление. Такое часто случается с HTML, но это потому, что HTML требует CSS для красивого представления; Flex может полностью обойтись без CSS.
При разработке один из нас обычно сразу разрабатывает большую часть кожи (имея стандартный каркас, как на ScaleNine, так как они делают фотошоп/флэш/афтер-эффекты. Нет способа избежать необходимости перекомпилировать css swf при внесении изменений. Но если он загружается во время выполнения, вам придется перекомпилировать только css-файл, а не основной swf, что полезно, но не очень полезно при хардкорной разработке скина.
Я пробовал держать основную таблицу стилей отдельно во время разработки (в пользовательской теме), и это значительно усложнило разработку, потому что мне приходилось перекомпилировать css отдельно каждый раз, когда я вносил изменения, а иногда приходилось перекомпилировать и основное приложение, и возникали странные и трудноотслеживаемые ошибки, и т.д. Тогда я компилировал два разных приложения. Поэтому я рекомендую держать основной css-файл в составе основного приложения.
Если вам нужен runtime css без необходимости что-то перекомпилировать, попробуйте Ruben's CSS Loader и посмотрите исходники. Но за это придется заплатить производительностью во время выполнения.