Сведения о вопросе

Математик

16:03, 1st July, 2020

Теги

0  

Просмотров: 387   Ответов: 0

сделать переключатель checkbox от нажатия на текстовую метку, а также?gfffg

Checkboxes в HTML формах не имеют неявных меток с ними. Добавление явной метки (некоторого текста) рядом с ней не переключает checkbox .

Как я могу сделать переключатель checkbox от нажатия на текстовую метку, а также?

gfffgttaagghtml,checkbox,ttaagggfffg

Если вы правильно markup свой код HTML, то нет никакой необходимости в javascript. Следующий код позволит пользователю нажать на текст метки, чтобы поставить галочку checkbox.

<label for="surname">Surname</label>
<input type="checkbox" name="surname" id="surname" />

Для атрибута элемента ярлыка ссылки на идентификатор атрибута на вход элемента и браузер делает rest.

Это было тестирование для работы в:

  • IE6
  • IE7
  • Firefox
llpp

Установите свойство CSS display для метки, чтобы она была блочным элементом, и используйте его вместо div - он сохраняет семантическое значение метки, позволяя использовать любой стиль, который вам нравится.

Например:

label {

  width: 100px;

  height: 100px;

  display: block;

  background-color: #e0e0ff;

}
<label for="test">

  A ticky box! <input type="checkbox" id="test" />

</label>

llpp

Как указано @Gatekiller и другими, правильным решением является тег <label>.

Click-in-the-text-это хорошо, но есть еще одна причина использовать тег <label>: доступность. Инструменты, которые люди с ослабленным зрением используют для доступа в интернет, нуждаются в <label>s, чтобы прочитать значение флажков и переключателей. Без <label>s, им приходится угадывать на основе окружающего текста, и они часто ошибаются или вынуждены сдаться.

Очень неприятно иметь дело с формой, которая читает "Please select your shipping method, radio-button1, radio-button2, radio-button3".

Обратите внимание, что доступность интернета-это сложная тема; <label>s являются необходимым шагом, но их недостаточно, чтобы гарантировать доступность или соблюдение государственных правил, где это применимо.

llpp

Ронни,

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

<label for="surname">
    Surname
    <input type="checkbox" name="surname" id="surname" />
</label>
llpp

Вы можете завернуть свой checkbox в этикетку:

<label style="display: block; padding: 50px 0 0 50px; background-color: pink; width: 80px; height: 80px">
  <input type="checkbox" name="surname">
</label>
llpp

Вам нужно просто обернуть checkbox в метку метки так же, как это

 <label style="height: 10px; width: 150px; display: block; ">
  [Checkbox Label Here] <input type="checkbox"/>
 </label>

FIDDLE

или вы также можете использовать атрибут for label и id вашего checkbox, как показано ниже

<label for="other">Other Details</label>
<input type="checkbox" id="other" />

FIDDLE

llpp

это должно сработать:

<script>
function checkbox () {
    var check = document.getElementById("myCheck").checked;
    var box = document.getElementById("myCheck")

    if (check == true) {
        box.checked = false;
    }
    else if (check == false) {
        box.checked = true;
    }
}
</script>
<input type="checkbox"><p id="myCheck" onClick="checkbox();">checkbox</p>

если это не так, то умоляю, кори меня!

llpp

Упаковка с этикеткой по - прежнему не позволяет нажимать "в любом месте коробки" - по-прежнему только на текст! Это делает работу за меня:

<div onclick="dob.checked=!dob.checked" class="checkbox"><input onclick="checked=!checked" id="dob" type="checkbox"/>Date of birth entry must be completed</div>

но, к сожалению, есть много javascript, который эффективно переключается дважды.

llppminhojkhonДействительно ли закрытые классы предлагают преимущества производительности?gfffg

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

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

Кто-нибудь проводил тесты и видел разницу?

Помоги мне учиться :)

gfffgttaagg.net,optimization,frameworks,performance,ttaagggfffg

Ответ-нет, запечатанные классы не работают лучше, чем не запечатанные.

Проблема сводится к кодам call vs callvirt IL op. Call быстрее , чем callvirt, и callvirt в основном используется, когда вы не знаете, был ли объект подклассом. Поэтому люди предполагают, что если вы запечатаете класс, все коды операций изменятся с calvirts на calls и будут быстрее.

К сожалению, callvirt делает и другие вещи, которые делают его полезным, например, проверка ссылок на null. Это означает, что даже если класс запечатан, ссылка все равно может быть null и, следовательно, требуется callvirt . Вы можете обойти это (без необходимости закрывать класс), но это становится немного бессмысленным.

Структуры используют call , потому что они не могут быть подклассами и никогда не являются null.

Смотрите этот вопрос для получения дополнительной информации:

Звони и вызывай Вирт

llpp

JITter иногда будет использовать невиртуальные вызовы методов в закрытых классах, так как они не могут быть расширены дальше.

Существуют сложные правила, касающиеся вызова type, virtual/nonvirtual,, и я не знаю их всех, поэтому я не могу точно описать их для вас, но если вы поищете в google закрытые классы и виртуальные методы, вы можете найти некоторые статьи по этой теме.

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

Вот одна ссылка, которая упоминает об этом: бессвязная речь на запечатанном ключевом слове

llpp

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

Но это зависит от реализации компилятора и среды выполнения.


Подробности

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

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

// Value of `v` is unknown,
// and can be resolved only at runtime.
// CPU cannot know which code to prefetch.
// Therefore, just prefetch any one of a() or b().
// This is *speculative execution*.
int v = random();
if (v==1) a();
else b();

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

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

Некоторые CPU (включая последние чипы Intel x86) используют технику, называемую спекулятивным исполнением , чтобы использовать конвейер даже в этой ситуации. Просто предварительно выберите один из путей выполнения. Но скорость попадания этой техники не так уж и высока. А неудача спекуляции приводит к остановке трубопровода, что также приводит к огромным потерям производительности. (это полностью по реализации CPU. некоторые мобильные CPU известен как не делает этот вид оптимизации для экономии энергии)

По сути, C#-это статически скомпилированный язык. Но не всегда. Я не знаю точного условия, и это полностью зависит от реализации компилятора. Некоторые компиляторы могут исключить возможность динамической отправки путем предотвращения переопределения метода, если метод помечен как sealed . Глупые компиляторы не могут этого сделать. Это-преимущество производительности sealed .


Этот ответ ( почему сортированный массив обрабатывается быстрее, чем несортированный? ) гораздо лучше описывает предсказание ветви.

llpp

Обновление: начиная с .NET Core 2.0 и .NET Desktop 4.7.1, CLR теперь поддерживает девиртуализацию. Он может принимать методы в запечатанных классах и заменять виртуальные вызовы прямыми вызовами - и он также может делать это для незапечатанных классов, если он может выяснить, что это безопасно.

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

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

https://blogs.msdn.microsoft.com/dotnet/2017/06/29/performance-improvements-in-ryujit-in-net-core-and-net-framework/


оригинальный ответ:

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

public class NormalClass {
    public void WriteIt(string x) {
        Console.WriteLine("NormalClass");
        Console.WriteLine(x);
    }
}

public sealed class SealedClass {
    public void WriteIt(string x) {
        Console.WriteLine("SealedClass");
        Console.WriteLine(x);
    }
}

public static void CallNormal() {
    var n = new NormalClass();
    n.WriteIt("a string");
}

public static void CallSealed() {
    var n = new SealedClass();
    n.WriteIt("a string");
}

Во всех случаях компилятор C# (Visual studio 2010 в конфигурации сборки выпуска) выдает идентичный MSIL, который выглядит следующим образом:

L_0000: newobj instance void <NormalClass or SealedClass>::.ctor()
L_0005: stloc.0 
L_0006: ldloc.0 
L_0007: ldstr "a string"
L_000c: callvirt instance void <NormalClass or SealedClass>::WriteIt(string)
L_0011: ret 

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

Моя следующая мысль была о том, что, хотя MSIL идентичен, возможно, компилятор JIT обрабатывает запечатанные классы по-разному?

Я запустил сборку выпуска под отладчиком visual studio и просмотрел декомпилированный вывод x86. В обоих случаях код x86 был идентичен, за исключением имен классов и адресов памяти функций (которые, конечно, должны быть разными). Вот оно

//            var n = new NormalClass();
00000000  push        ebp 
00000001  mov         ebp,esp 
00000003  sub         esp,8 
00000006  cmp         dword ptr ds:[00585314h],0 
0000000d  je          00000014 
0000000f  call        70032C33 
00000014  xor         edx,edx 
00000016  mov         dword ptr [ebp-4],edx 
00000019  mov         ecx,588230h 
0000001e  call        FFEEEBC0 
00000023  mov         dword ptr [ebp-8],eax 
00000026  mov         ecx,dword ptr [ebp-8] 
00000029  call        dword ptr ds:[00588260h] 
0000002f  mov         eax,dword ptr [ebp-8] 
00000032  mov         dword ptr [ebp-4],eax 
//            n.WriteIt("a string");
00000035  mov         edx,dword ptr ds:[033220DCh] 
0000003b  mov         ecx,dword ptr [ebp-4] 
0000003e  cmp         dword ptr [ecx],ecx 
00000040  call        dword ptr ds:[0058827Ch] 
//        }
00000046  nop 
00000047  mov         esp,ebp 
00000049  pop         ebp 
0000004a  ret 

Затем я подумал, что, возможно, запуск под отладчиком заставляет его выполнять менее агрессивную оптимизацию?

Затем я запустил исполняемый файл сборки автономного выпуска вне любых сред отладки и использовал WinDBG + SOS для взлома после завершения программы и просмотра разборки JIT скомпилированного кода x86.

Как вы можете видеть из приведенного ниже кода, при запуске вне отладчика компилятор JIT более агрессивен, и он встроил метод WriteIt прямо в вызывающий объект. Однако самое главное, что он был идентичен при вызове запечатанного или не запечатанного класса. Нет никакой разницы между запечатанным или негерметичным классом.

Вот она при вызове обычного класса:

Normal JIT generated code
Begin 003c00b0, size 39
003c00b0 55              push    ebp
003c00b1 8bec            mov     ebp,esp
003c00b3 b994391800      mov     ecx,183994h (MT: ScratchConsoleApplicationFX4.NormalClass)
003c00b8 e8631fdbff      call    00172020 (JitHelp: CORINFO_HELP_NEWSFAST)
003c00bd e80e70106f      call    mscorlib_ni+0x2570d0 (6f4c70d0) (System.Console.get_Out(), mdToken: 060008fd)
003c00c2 8bc8            mov     ecx,eax
003c00c4 8b1530203003    mov     edx,dword ptr ds:[3302030h] ("NormalClass")
003c00ca 8b01            mov     eax,dword ptr [ecx]
003c00cc 8b403c          mov     eax,dword ptr [eax+3Ch]
003c00cf ff5010          call    dword ptr [eax+10h]
003c00d2 e8f96f106f      call    mscorlib_ni+0x2570d0 (6f4c70d0) (System.Console.get_Out(), mdToken: 060008fd)
003c00d7 8bc8            mov     ecx,eax
003c00d9 8b1534203003    mov     edx,dword ptr ds:[3302034h] ("a string")
003c00df 8b01            mov     eax,dword ptr [ecx]
003c00e1 8b403c          mov     eax,dword ptr [eax+3Ch]
003c00e4 ff5010          call    dword ptr [eax+10h]
003c00e7 5d              pop     ebp
003c00e8 c3              ret

Против запечатанного класса:

Normal JIT generated code
Begin 003c0100, size 39
003c0100 55              push    ebp
003c0101 8bec            mov     ebp,esp
003c0103 b90c3a1800      mov     ecx,183A0Ch (MT: ScratchConsoleApplicationFX4.SealedClass)
003c0108 e8131fdbff      call    00172020 (JitHelp: CORINFO_HELP_NEWSFAST)
003c010d e8be6f106f      call    mscorlib_ni+0x2570d0 (6f4c70d0) (System.Console.get_Out(), mdToken: 060008fd)
003c0112 8bc8            mov     ecx,eax
003c0114 8b1538203003    mov     edx,dword ptr ds:[3302038h] ("SealedClass")
003c011a 8b01            mov     eax,dword ptr [ecx]
003c011c 8b403c          mov     eax,dword ptr [eax+3Ch]
003c011f ff5010          call    dword ptr [eax+10h]
003c0122 e8a96f106f      call    mscorlib_ni+0x2570d0 (6f4c70d0) (System.Console.get_Out(), mdToken: 060008fd)
003c0127 8bc8            mov     ecx,eax
003c0129 8b1534203003    mov     edx,dword ptr ds:[3302034h] ("a string")
003c012f 8b01            mov     eax,dword ptr [ecx]
003c0131 8b403c          mov     eax,dword ptr [eax+3Ch]
003c0134 ff5010          call    dword ptr [eax+10h]
003c0137 5d              pop     ebp
003c0138 c3              ret

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

llpp

Маркировка класса sealed не должна оказывать никакого влияния на производительность.

Есть случаи, когда csc , возможно, придется выдавать код callvirt вместо кода call . Однако, похоже, такие случаи редки.

И мне кажется, что JIT должен быть способен выдавать тот же невиртуальный вызов функции для callvirt , что и для call, если он знает, что класс не имеет подклассов (пока). Если существует только одна реализация метода, нет смысла загружать его адрес из vtable—просто вызовите одну реализацию напрямую. Если уж на то пошло, то JIT может даже встроить эту функцию.

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

(И да, дизайнеры VM действительно агрессивно преследуют эти крошечные выигрыши в производительности.)

llpp

Я считаю классы "sealed" нормальным случаем, и у меня всегда есть причина опустить ключевое слово "sealed".

Наиболее важными причинами для меня являются:

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

и, главная причина:

b) злоупотребление моими классами невозможно таким образом

Я бы хотел, чтобы Microsoft сделала стандарт "sealed", а не "unsealed".

llpp

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

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

llpp

<off-topic-rant>

Я ненавижу закрытые классы. Даже если преимущества производительности поразительны (в чем я сомневаюсь), они разрушают объектно-ориентированную модель, предотвращая повторное использование через наследование. Например, класс Thread является запечатанным. Хотя я вижу, что можно было бы хотеть, чтобы потоки были как можно более эффективными, я также могу представить себе сценарии, в которых возможность подкласса потока будет иметь большие преимущества. Авторы классов, если вы должны запечатать свои классы по "performance" причинам, пожалуйста, предоставьте интерфейс по крайней мере, чтобы нам не пришлось wrap-and-replace везде, где нам нужна функция, которую вы забыли.

Пример: SafeThread пришлось обернуть класс Thread, потому что Thread запечатан и нет интерфейса IThread; SafeThread автоматически ловит необработанные исключения на потоках, что-то полностью отсутствует в классе Thread. [и нет, необработанные события исключений не собирают необработанные исключения во вторичных потоках].

</off-topic-rant>

llpp

@Vaibhav, какие тесты вы выполняли для измерения производительности?

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

SSCLI (Ротор)
SSCLI: Общий Исходный Код Инфраструктура Общего Языка

Инфраструктура Общего Языка (CLI) - это стандарт ECMA, который описывает ядро .NET Рамки. Общий Источник CLI (SSCLI), также известный как Ротор, является сжатый архив исходного кода к рабочей реализации проекта ECMA CLI и язык ECMA C# спецификация, технологии на сердце Microsoft .NET архитектура.

llpp

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

Тем не менее, лучшая причина запечатать класс-это сказать: "я не создавал его для наследования, поэтому я не позволю вам обжечься, предполагая, что он был спроектирован таким образом, и я не собираюсь сжигать себя, запираясь в реализации, потому что я позволяю вам выводить из него."

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

llpp

Запустите этот код, и вы увидите, что запечатанные классы работают в 2 раза быстрее:

class Program
{
    static void Main(string[] args)
    {
        Console.ReadLine();

        var watch = new Stopwatch();
        watch.Start();
        for (int i = 0; i < 10000000; i++)
        {
            new SealedClass().GetName();
        }
        watch.Stop();
        Console.WriteLine("Sealed class : {0}", watch.Elapsed.ToString());

        watch.Start();
        for (int i = 0; i < 10000000; i++)
        {
            new NonSealedClass().GetName();
        }
        watch.Stop();
        Console.WriteLine("NonSealed class : {0}", watch.Elapsed.ToString());

        Console.ReadKey();
    }
}

sealed class SealedClass
{
    public string GetName()
    {
        return "SealedClass";
    }
}

class NonSealedClass
{
    public string GetName()
    {
        return "NonSealedClass";
    }
}

выход: Герметичный класс: 00:00:00.1897568 NonSealed класс : 00:00:00.3826678

llppminhojkhonLINQ в среде выполнения .NET 2.0gfffg

Может ли приложение с поддержкой LINQ работать на машине, на которой установлена только среда выполнения .NET 2.0?

В теории, LINQ - это не более чем синтаксический сахар, и полученный код IL должен выглядеть так же, как и в .NET 2.0.

Как я могу написать LINQ без использования библиотек .NET 3.5? Будет ли он работать на .NET 2.0?

gfffgttaagg.net,linq,.net-3.5,.net-2.0,clr,ttaagggfffg

Странно, что никто не упомянул LINQBridge . Этот маленький удивительный проект является бэкпортом LINQ (IEnumerable, но без IQueryable) и его зависимостей (Func, Action и т. д.) К .NET 2.0. И:

Если ваш проект ссылается на LINQBridge во время компиляции, то он будет привязываться к операторам запроса LINQBridge; если это ссылки System.Core во время компиляции, то он будет привязан к Операторы запросов Framework 3.5's.

llpp

Есть некоторые "Hacks", которые включают в себя использование System.Core.dll из фреймворка 3.5, чтобы заставить его работать с .net 2.0, но лично я не хотел бы использовать такой несколько шаткий фундамент.

Смотрите здесь: поддержка LINQ на .NET 2.0

  1. Создание нового консольного приложения
  2. Сохраняйте только системные и System.Core в качестве ссылочных сборок
  3. Установите Copy Local в true для System.Core, так как он не существует в .NET 2.0
  4. Используйте запрос LINQ в основном методе. Например, тот, что ниже.
  5. Строить
  6. Скопируйте все выходные данные bin на машину, где установлен только .NET 2.0
  7. Бежать

(Требуется .net 2.0 SP1, и я понятия не имею, если связывание System.Core.dll нарушает EULA)

llpp

Теоретически да, при условии, что вы распространяете LINQ конкретных сборок и любых зависимостей. Однако это является нарушением лицензирования Microsoft. Скотт Ханселман написал сообщение в блоге о развертывании ASP.NET MVC на ASP.NET 2.0 , которое похоже на то, что вы хотите сделать.

llpp

Вы можете использовать LINQ источника из mono (.NET для Linux), чтобы заставить LINQ работать на .NET 2.0.

IEnumerable<T> : yes 
IQueryable<T>  : yes
LINQ to XML : has been working in the trunk, but due to further additions, the trunk doesn't compile anymore

Кто-то уже сделал это здесь:
LINQ для .NET 2.0

llpp

Короткий ответ:

  • LINQ для объектов: да ( IEnumerable<T> )
  • От LINQ до SQL/Entities: нет ( IQueryable<T> )
  • LINQ - XML/DataSets: еще нет?

Смотрите этот вопрос о функциях .Net 3.5, доступных автоматически или без особых усилий при таргетировании .Net 2.0 из VS2008.

В принципе, все, что только "syntax sugar" и новые компиляторы (C# 3.0, VB 9.0) испускают как 2.0-compatible IL, будет работать. Это включает в себя множество функций, используемых LINQ, таких как анонимные классы, лямбды в качестве анонимных делегатов, автоматические свойства, инициализаторы объектов и инициализаторы коллекций.

Некоторые функции LINQ используют классы, интерфейсы, делегаты и методы расширения, которые живут в новых сборках 3.5 (например, System.Core.dll). Распространение этих сборок является нарушением лицензии, но они могут быть повторно реализованы. При использовании методов расширения нужно только, чтобы вы объявили пустой System.Runtime.CompilerServices.ExtensionAttribute . LINQ to Objects опирается на расширения IEnumerable<T> и несколько деклараций делегатов (семейства Action<T> и Func<T> ) и были реализованы в LINQBridge (как упоминалось выше). LINQ к XML и LINQ к DataSets полагаются на LINQ к объектам, которые, как я предполагаю, также могут быть реализованы для .Net 2.0, но я еще не видел, как это делается.

Для сущностей от LINQ до SQL и от LINQ до сущностей требуется много новых классов (DataContext / ObjectContext , множество атрибутов, EntitySet<T> , EntityRef<T> , Link<T> , IQueryable<T> и т. д.) и деревьев выражений , которые, даже если они каким-то образом будут переосмыслены, вероятно, потребуют как минимум .Net 2.0 SP1 для работы.

llpp

Я не уверен насчет C#.

Однако я знаю, что вы можете написать код VB LINNQ без библиотек 3.5, если вы используете компилятор VS 2008 для целевой платформы 2.0.

Однако вам придется реализовать некоторые из методов LINQ самостоятельно.

LINQ использует синтаксическое преобразование для перевода запросов в исполняемый код. В принципе, он будет принимать такой код:

dim q = from x in xs where x > 2 select x*4;

и преобразуйте его в код вот так:

dim q = xs.where(function(x) x > 2).select(function(x) x * 4);

Для функциональности LINQ, которая поставляется с платформой 3.5, эти методы реализуются как методы расширения либо на IEnumerable, либо на IQueryable (есть также куча методов, которые также работают с наборами данных).

Методы расширения по умолчанию IEnumerable определены в System.Linq.Enumerable и выглядят следующим образом:

<Extension()>
public function Select(of T, R)(source as IEnumerable(of T), transform as Func(of T, R)) as IEnumerable(of R)

   'do the transformation...

end function

Методы расширения IQueryable принимают деревья выражений в качестве аргументов, а не лямбды. Они выглядят вот так:

 <Extension()>
 public function Select(of T, R)(source as IQueryable<T>, transform as Expression(of Func(of T, R))
     'build a composite IQueryable that contains the expression tree for the transformation
 end function

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

Вероятно, вы могли бы создать свою собственную версию LINQ для объектов примерно за день или около того. Все это довольно прямолинейно.

Если вы хотите использовать DLINQ, то все будет немного сложнее.

llpp

Нет, потому что в то время как вы думали, что LINQ-это просто синтаксический сахар, на самом деле он сильно использовал деревья выражений-особенность, отсутствующая в .NET 2.0.

Это, как говорится .NET 3.5 только накапливается на верхней части .NET 2.0, и это причина, почему IL не выглядит "different" или "special".

Я не вижу причин, почему бы вам просто не установить фреймворк .NET 3.5. Все .NET 2.0 будет работать нормально, обещаю :)

llpp

Насколько мне известно, библиотека LINQ доступна только после фреймворка 3.0. Если вы хотите использовать что-то подобное в framework 2.0, вам нужно будет переписать его самостоятельно :) или найти аналогичную стороннюю библиотеку. Я нашел здесь только немного информации, но и она меня не убедила.

llpp

Вы можете использовать linqbridge для .net 2.0

llppminhojkhonРазработка для ASP.NET-MVC без Visual Studiogfffg

Вместо написания моих ASP.NET C# приложений в Visual Studio я использовал мой любимый текстовый редактор UltraEdit32.

Есть ли вообще возможность реализовать MVC без использования VS?

gfffgttaaggc#,asp.net-mvc,visual-studio,ttaagggfffg

В фреймворке MVC нет ничего специфичного для VS-это просто набор DLLs, который вы можете использовать. Мастера в VS просто построят вам быстрый стартовый фреймворк.

ASP.NET MVC - это "bin-deployable" - там нет ничего слишком умного, чтобы настроить на сервере либо - просто укажите подстановочный знак ISAPI фильтр на ASP.NET

llpp

Предполагая, что у вас есть правильные сборки и компилятор C#, вы теоретически можете использовать все, что хотите, чтобы отредактировать код, а затем просто запустить компилятор вручную или с помощью сценария сборки. Тем не менее, это настоящая боль, делая .NET развитие без визуального Studio/SharpEdit/Monodevelop на мой взгляд.

llpp

Даже если вы не хотите на самом деле редактировать в VS, вы можете создать проект там и редактировать файлы в другом редакторе.

llpp

Для малого и среднего размера MVC project WebMatrix совсем не плох. Также для простых изменений в проектах я часто использую SublimeText.

llppminhojkhonКак определить пользовательские секции web.config с потенциальными дочерними элементами и атрибутами для свойств?gfffg

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

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

Каков наилучший способ создания пользовательских разделов конфигурации и есть ли какие-либо особые соображения, которые следует учитывать при извлечении значений?

gfffgttaaggasp.net,ttaagggfffg

Использование атрибутов, дочерних разделов конфигурации и ограничений

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

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

MailCenterConfiguration.cs:

namespace Ani {

    public sealed class MailCenterConfiguration : ConfigurationSection
    {
        [ConfigurationProperty("userDiskSpace", IsRequired = true)]
        [IntegerValidator(MinValue = 0, MaxValue = 1000000)]
        public int UserDiskSpace
        {
            get { return (int)base["userDiskSpace"]; }
            set { base["userDiskSpace"] = value; }
        }
    }
}

Это настроено в web.config примерно так

<configSections>
    <!-- Mailcenter configuration file -->
    <section name="mailCenter" type="Ani.MailCenterConfiguration" requirePermission="false"/>
</configSections>
...
<mailCenter userDiskSpace="25000">
    <mail
     host="my.hostname.com"
     port="366" />
</mailCenter>

Дочерний элемент

Дочерний элемент xml mail создается в том же файле .cs, что и приведенный выше. Здесь я добавил ограничения на порт. Если порту присвоено значение не в этом диапазоне, среда выполнения будет жаловаться при загрузке конфигурации.

MailCenterConfiguration.cs:

public sealed class MailCenterConfiguration : ConfigurationSection
{
    [ConfigurationProperty("mail", IsRequired=true)]
    public MailElement Mail
    {
        get { return (MailElement)base["mail"]; }
        set { base["mail"] = value; }
    }

    public class MailElement : ConfigurationElement
    {
        [ConfigurationProperty("host", IsRequired = true)]
        public string Host
        {
            get { return (string)base["host"]; }
            set { base["host"] = value; }
        }

        [ConfigurationProperty("port", IsRequired = true)]
        [IntegerValidator(MinValue = 0, MaxValue = 65535)]
        public int Port
        {
            get { return (int)base["port"]; }
            set { base["port"] = value; }
        }

Воспользуйся

Чтобы затем использовать его практически в коде, все, что вам нужно сделать, это создать экземпляр MailCenterConfigurationObject, это автоматически прочитает соответствующие разделы из web.config.

MailCenterConfiguration.cs

private static MailCenterConfiguration instance = null;
public static MailCenterConfiguration Instance
{
    get
    {
        if (instance == null)
        {
            instance = (MailCenterConfiguration)WebConfigurationManager.GetSection("mailCenter");
        }

        return instance;
    }
}

AnotherFile.cs

public void SendMail()
{
    MailCenterConfiguration conf = MailCenterConfiguration.Instance;
    SmtpClient smtpClient = new SmtpClient(conf.Mail.Host, conf.Mail.Port);
}

Проверка на валидность

Я уже упоминал, что среда выполнения будет жаловаться, когда конфигурация загружается и некоторые данные не соответствуют установленным вами правилам (например, в MailCenterConfiguration.cs). Я, как правило, хочу знать эти вещи как можно скорее, когда мой сайт загорается. Один из способов решить эту проблему-загрузить конфигурацию в _Global.asax.cx.Application_Start_ , если конфигурация недействительна, вы будете уведомлены об этом с помощью исключения. Ваш сайт не запустится, и вместо этого вам будет представлена подробная информация об исключениях в Желтом экране смерти .

Global.asax.cs

protected void Application_ Start(object sender, EventArgs e)
{
    MailCenterConfiguration.Instance;
}
llpp

Быстрая, нежели грязная:

Сначала создайте свои классы ConfigurationSection и ConfigurationElement :

public class MyStuffSection : ConfigurationSection
{
    ConfigurationProperty _MyStuffElement;

    public MyStuffSection()
    {
        _MyStuffElement = new ConfigurationProperty("MyStuff", typeof(MyStuffElement), null);

        this.Properties.Add(_MyStuffElement);
    }

    public MyStuffElement MyStuff
    {
        get
        {
            return this[_MyStuffElement] as MyStuffElement;
        }
    }
}

public class MyStuffElement : ConfigurationElement
{
    ConfigurationProperty _SomeStuff;

    public MyStuffElement()
    {
        _SomeStuff = new ConfigurationProperty("SomeStuff", typeof(string), "<UNDEFINED>");

        this.Properties.Add(_SomeStuff);
    }

    public string SomeStuff
    {
        get
        {
            return (String)this[_SomeStuff];
        }
    }
}

Затем дайте фреймворку знать, как обрабатывать ваши классы конфигурации в web.config :

<configuration>
  <configSections>
    <section name="MyStuffSection" type="MyWeb.Configuration.MyStuffSection" />
  </configSections>
  ...

И на самом деле добавьте свой собственный раздел ниже:

  <MyStuffSection>
    <MyStuff SomeStuff="Hey There!" />
  </MyStuffSection>

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

MyWeb.Configuration.MyStuffSection configSection = ConfigurationManager.GetSection("MyStuffSection") as MyWeb.Configuration.MyStuffSection;

if (configSection != null && configSection.MyStuff != null)
{
    Response.Write(configSection.MyStuff.SomeStuff);
}
llpp

Есть отличный пример на MSDN , использующий ConfigurationCollection и .NET 4.5 для пользовательских разделов в web.config, который содержит список элементов конфигурации.

llpp

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

Для .NET 1.1 обратитесь к статье http://aspnet.4guysfromrolla.com/articles/020707-1.aspx

Примечание: вышеуказанное решение работает и для .NET 2.0.

Для .NET 2.0 конкретного решения, пожалуйста, обратитесь к статье http://aspnet.4guysfromrolla.com/articles/032807-1.aspx

llpp

Это можно сделать с помощью обработчиков разделов. Существует основной обзор того, как написать один из них в http://www.codeproject.com/KB/aspnet/ConfigSections.aspx , однако он относится к app.config, что было бы почти то же самое, что написать один для использования в web.config. Это позволит вам, по существу, иметь свое собственное дерево XML в конфигурационном файле и выполнить некоторые более продвинутые настройки.

llpp

Самый простой метод, который я нашел, - это использование секции appSettings .

  1. Добавьте к Web.config следующее:

    <appSettings>
        <add key="MyProp" value="MyVal"/>
    </appSettings>
    

llppminhojkhonСоздание пользовательского JButton в Javagfffg

Есть ли способ создать JButton с вашим собственным графическим изображением кнопки, а не только с изображением внутри кнопки?

Если нет, то есть ли другой способ создать пользовательский JButton в java?

gfffgttaaggjava,swing,jbutton,ttaagggfffg

Когда я только учился Java, мы должны были сделать Yahtzee, и я подумал, что было бы здорово создать пользовательские компоненты Swing и контейнеры вместо того, чтобы просто рисовать все на одном JPanel . Преимущество расширения компонентов Swing , конечно, состоит в том, чтобы иметь возможность добавить поддержку сочетаний клавиш и других специальных возможностей, которые вы не можете сделать, просто имея метод paint() для печати красивой картинки. Однако это может быть сделано не лучшим образом, но это может быть хорошей отправной точкой для вас.

Edit 8/6-если это не было видно из изображений,каждый кубик - это кнопка, которую вы можете нажать. Это переместит его на DiceContainer ниже. Глядя на исходный код, вы можете увидеть, что каждая кнопка штампа рисуется динамически, исходя из ее значения.

alt text
alt text
alt text

Вот основные шаги:

  1. Создайте класс, который расширяет JComponent
  2. Вызовите родительский конструктор super() в ваших конструкторах
  3. Убедитесь, что ваш класс реализует MouseListener
  4. Поместите это в конструктор:

    enableInputMethods(true);   
    addMouseListener(this);
    
  5. Переопределение этих методов:

    public Dimension getPreferredSize()  
    public Dimension getMinimumSize()  
    public Dimension getMaximumSize()
    
  6. Переопределить этот метод:

    public void paintComponent(Graphics g)
    

Объем пространства , с которым вы должны работать при рисовании кнопки, определяется параметром getPreferredSize(), предполагая, что getMinimumSize() и getMaximumSize() возвращают одно и то же значение. Я не слишком экспериментировал с этим, но в зависимости от макета, который вы используете для вашего GUI, ваша кнопка может выглядеть совершенно по-другому.

И, наконец, исходный код . На случай, если я что-нибудь упущу.

llpp

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

Вот быстрый и грязный способ расширить существующий класс JButton, чтобы нарисовать круг справа от текста.

package test;

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;

import javax.swing.JButton;
import javax.swing.JFrame;

public class MyButton extends JButton {

    private static final long serialVersionUID = 1L;

    private Color circleColor = Color.BLACK;

    public MyButton(String label) {
        super(label);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Dimension originalSize = super.getPreferredSize();
        int gap = (int) (originalSize.height * 0.2);
        int x = originalSize.width + gap;
        int y = gap;
        int diameter = originalSize.height - (gap * 2);

        g.setColor(circleColor);
        g.fillOval(x, y, diameter, diameter);
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension size = super.getPreferredSize();
        size.width += size.height;
        return size;
    }

    /*Test the button*/
    public static void main(String[] args) {
        MyButton button = new MyButton("Hello, World!");

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);

        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new FlowLayout());
        contentPane.add(button);

        frame.setVisible(true);
    }

}

Обратите внимание, что при переопределении paintComponent содержимое кнопки может быть изменено, но граница окрашена методом paintBorder . Метод getPreferredSize также нуждается в управлении для динамической поддержки изменений содержимого. При измерении метрик шрифтов и размеров изображений необходимо соблюдать осторожность.

Для создания элемента управления, на который можно положиться, приведенный выше код не является правильным подходом. Размеры и цвета динамичны в Swing и зависят от используемого внешнего вида и ощущения. Даже внешний вид металла по умолчанию изменился в версиях JRE. Было бы лучше осуществить AbstractButton и соответствовать руководящим принципам, изложенным в Swing API. Хорошей отправной точкой является рассмотрение классов javax.swing.LookAndFeel и javax.swing.UIManager .

http://docs.oracle.com/javase/8/docs/api/javax/swing/LookAndFeel.html

http://docs.oracle.com/javase/8/docs/api/javax/swing/UIManager.html

Понимание анатомии LookAndFeel полезно для написания элементов управления: Создание пользовательского внешнего вида

llpp

Вы всегда можете попробовать синтезатор look & feel. Вы предоставляете файл xml, который действует как своего рода таблица стилей, а также любые изображения, которые вы хотите использовать. Код может выглядеть следующим образом:

try {
    SynthLookAndFeel synth = new SynthLookAndFeel();
    Class aClass = MainFrame.class;
    InputStream stream = aClass.getResourceAsStream("\\default.xml");

    if (stream == null) {
        System.err.println("Missing configuration file");
        System.exit(-1);                
    }

    synth.load(stream, aClass);

    UIManager.setLookAndFeel(synth);
} catch (ParseException pe) {
    System.err.println("Bad configuration file");
    pe.printStackTrace();
    System.exit(-2);
} catch (UnsupportedLookAndFeelException ulfe) {
    System.err.println("Old JRE in use. Get a new one");
    System.exit(-3);
}

Оттуда продолжайте и добавьте свой JButton, как вы обычно это делаете. Единственное изменение заключается в том, что вы используете метод setName(string), чтобы определить, к чему должна соответствовать кнопка в файле xml.

Файл xml может выглядеть следующим образом:

<synth>
    <style id="button">
        <font name="DIALOG" size="12" style="BOLD"/>
        <state value="MOUSE_OVER">
            <imagePainter method="buttonBackground" path="dirt.png" sourceInsets="2 2 2 2"/>
            <insets top="2" botton="2" right="2" left="2"/>
        </state>
        <state value="ENABLED">
            <imagePainter method="buttonBackground" path="dirt.png" sourceInsets="2 2 2 2"/>
            <insets top="2" botton="2" right="2" left="2"/>
        </state>
    </style>
    <bind style="button" type="name" key="dirt"/>
</synth>

Элемент bind там указывает, что нужно сопоставить (в этом примере он будет применять этот стиль к любым кнопкам, свойство name которых было установлено в "dirt").

И еще пара полезных ссылок:

http://javadesktop.org/articles/synth/

http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synth.html

llpp

Я, вероятно, проеду миллион миль в неправильном направлении (но я только молод :P). но не могли бы вы добавить графический элемент на панель, а затем mouselistener к графическому объекту, чтобы при появлении пользователя на графике ваше действие было предварительно сформировано.

llpp

Я не занимался SWING разработкой с момента моего раннего CS класса, но если он не был встроен, вы можете просто унаследовать javax.swing.AbstractButton и создать свой собственный. Должно быть довольно просто связать что-то вместе с их существующей структурой.

llppminhojkhonПростой способ AJAX WebControlsgfffg

У меня есть веб-приложение, которое я пытаюсь оптимизировать. Некоторые элементы управления скрыты в диалоговом стиле DIVs . Итак, я хотел бы, чтобы они загружались через AJAX только тогда, когда пользователь хочет их видеть. Это хорошо для элементов управления, которые в основном основаны на литералах (различные меню и виджеты), но когда у меня есть то , что я называю "dirty" элементами управления - те, которые пишут обширную информацию в ViewState, помещают тонны CSS или скрипта на страницу, требуют много ссылок и т. д. - Это, по-видимому, невозможно переместить "из страницы", особенно учитывая, как ASP.NET будет реагировать на обратную передачу.

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

В моем воспаленном воображении, я хочу сделать это:

AJAXifier.AJAXify(ctlEditForm);

К сожалению, я знаю, что это сон.

Как близко я могу подойти к quick-and-easy AJAXification, не вызывая слишком большой нагрузки на сервер?

gfffgttaaggasp.net,ajax,web-controls,ttaagggfffg

Проверьте элемент управления RadAjax из Telerik-это позволяет избежать использования UpdatePanels и ограничить количество информации, передаваемой между сервером и клиентом, объявив прямые отношения между вызывающими элементами управления и элементами управления, которые должны быть "Ajaxified", когда вызывающие элементы управления отправляют обратные передачи.

llpp

Я рекомендую вам пойти в местный книжный магазин в эти выходные, выпить чашечку кофе и найти jQuery в действии от Manning Press. Идите вперед и прочитайте первую главу этой 300-страничной книги в магазине, а затем купите ее, если она резонирует с вами.

Я думаю, вы будете удивлены тем, как легко jQuery позволяет вам выполнять то, что вы описываете здесь. От ajax вызовов к серверу в фоновом режиме, чтобы показать и скрыть теги div на основе действий посетителя. Количество кода, который вы должны написать, очень мало.

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

llpp

Шаг первый-сделать ваши "dirty" штук автономными пользовательскими элементами управления

Шаг второй-внедрить эти элементы управления на Вашей странице потребления

Шаг третий-обернуть каждый тег пользовательского элемента управления в свой собственный Asp:UpdatePanel

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

Ваш пробег может отличаться.

llppminhojkhonКак я могу изменить фон главной страницы из кода позади страницы содержимого?gfffg

Я специально хочу добавить стиль background-color к тегу <body> главной страницы из кода за (C#) страницы содержимого, которая использует эту главную страницу.

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

У меня есть решение ниже:


Я ищу что-то более похожее:

Master.Attributes.Add("style", "background-color: 2e6095");

Внутри страницы функция загрузки страницы содержимого. Но я не могу заставить эту линию работать. Мне нужно только изменить background-color для тега <body> страницы.

gfffgttaaggc#,asp.net,.net,master-pages,ttaagggfffg

То, что я бы сделал для конкретного случая, это:

i. определите тело как серверный элемент управления

<body runat="server" id="masterpageBody">

второй. В aspx-страницу содержимого, зарегистрировать MasterPage с регистром:

<% MasterPageFile="..." %>

iii. на странице содержимого теперь вы можете просто использовать

Master.FindControl("masterpageBody")

и иметь доступ к управлению. Теперь вы можете изменить любые свойства / стиль, которые вам нравятся!

llpp

Вот что я придумал:

В функции загрузки страницы:

HtmlGenericControl body = (HtmlGenericControl)Master.FindControl("default_body");
body.Style.Add(HtmlTextWriterStyle.BackgroundColor, "#2E6095");

Где

default_body = идентификатор тега body.

llpp

Я полагаю, что вы говорите о системе управления контентом. То, как я справлялся с этой ситуацией в прошлом, заключается в том, чтобы либо:

  1. Разрешить странице / контенту определять дополнительную пользовательскую таблицу стилей или
  2. Разрешить странице / контенту определять встроенные теги стилей
llppminhojkhonКак лучше всего реализовать BDD/TDD в .NET 2.0?gfffg

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

Есть ли у кого-нибудь предложения о хороших тестовых фреймворках для использования?

gfffgttaaggc#,.net,testing,tdd,bdd,ttaagggfffg

NUnit и Носорог хорошо подходят, и контейнер с автоматической насмешкой может представлять интерес.

Если вы тоже смотрите на BDD, то NBehave , вероятно, хороший выбор. Если, однако, вы просто имеете в виду стиль BDD, который относится к модульному тестированию (xSpec), хотя вам может сойти с рук добавление фреймворка (хотя такие вещи, как specunit , добавляют некоторый синктактический сахар), но вы можете посмотреть на MSpec также интересно.

llpp

Мы используем MbUnit и насмешки Рино, и они очень хорошо работают вместе. Когда вы делаете TDD, вам почти наверняка нужно будет сделать какую-то форму инъекции зависимостей, хотя это можно сделать вручную, стоит посмотреть на контейнер IoC, такой как замок Виндзор .

Стоит посмотреть на экранные слепки Джона Пола Бодхуда, чтобы начать работу. Блог JPB по

llpp

Проверьте показ Роба Конери на BDD с помощью MSpec. Очень впечатляет http://blog.wekeroad.com/mvc-storefront/kona-3/

edit: теперь я использую такой подход: http://10printhello.com/the-one-bdd-framework-to-rule-them/

llpp

Для библиотеки макетов объектов я нашел BSD-лицензионный Rhino.Mocks довольно приятным.

llpp

Я также имел большой успех, используя NUnit .

Я также использовал NMock , когда возникла необходимость в макетах объектов. В качестве дополнительного бонуса фабрика по созданию ваших макетов называется Mockery.

Чтобы облегчить выполнение модульных тестов, я использовал TestDriven.NET для запуска модульных тестов по мере их кодирования. Кроме того, я использовал круиз-контроль .NET , чтобы смотреть SVN и проверять, что каждый новый коммит строится и проходит все юнит-тесты.

llpp

Это, вероятно, краткое изложение того, что уже было сказано, но для TDD я лично использую Rhino Mocks и MBUnit. Rhino Mocks-это издевательский фреймворк, который является свободным и открытым исходным кодом. Преимущество Rhino Mocks заключается в том, что нам не нужно использовать магические строки для установления ваших ожиданий, как это делается в NMock.

Мне нравится MBUnit, потому что MbUnit имеет концепцию RowTests, которая позволяет вам варьировать свои входные данные в соответствии с вашим методом тестирования. MBUnit также находится в свободном доступе.

Вы также хотите убедиться, что все, что вы выберете для своей платформы модульного тестирования, поддерживается вашим CI (сервером непрерывной интеграции). Nunit поддерживается по умолчанию в Cruise Control.NET, и вам нужно сделать немного дополнительной работы, чтобы заставить MBUnit работать в ccnet.

С точки зрения IDE вы должны иметь TestDriven.NET. TestDriven.NET позволяет вам щелкнуть правой кнопкой мыши и запустить тесты в IDE, а также поддерживает MBUnit и Nunit и другие.

NBehave - это библиотека BDD, которую я использовал. Я не использовал другие тесты, поэтому не мог сравнивать и сравнивать их с вами, но NBehave поддерживается Gallio из команды MBUnit, что означает, что вы можете запускать свои тесты BDD точно так же, как и юнит-тесты с TestDriven.NET.

Я бы также очень рекомендовал Resharper. Вы обнаружите, что ваша производительность значительно возрастает с помощью этого инструмента рефакторинга и руководства. Это поможет вам изменить код при разработке тестов.

Надеюсь, это поможет

llpp

NUnit доступен в http://www.nunit.org я бы предложил это даже при работе над стеком MS - поддержка не-MS фреймворков происходит в MVC превью, которое показывает определенное движение в правильном направлении, чтобы позволить нам всем настроить наши стеки под себя.

llpp

Использовать nUnit с TFS не так уж и сложно. Есть даже проект на codeplex, чтобы реализовать это: NUnit для Team Build , который даже "publishes" результаты на склад.

Я не пробовал его , но я бы посоветовал клиентам, которые имеют большие инвестиции (или которые имеют сильное предпочтение перед инструментом MSTest) в nUnit, которые заинтересованы в реализации TFS, продолжать использовать nUnit, а не пытаться конвертировать все существующие тесты.

llpp

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

Инструменты тестирования, встроенные в TFS, хороши, они сделают свою работу, но часто могут быть немного громоздкими для работы. Сгенерированные отчеты, покрытие кода и некоторые другие части особенно плохи, они заставляют вас лысеть в 22, а не в 50 лет.

Если вы действительно любите тестирование, подумайте о том, чтобы попробовать какую-то непрерывную интеграцию. Вы быстро почувствуете боль от регрессии и потенциально сможете быстрее добраться до конечной цели.

Независимо от того, что вы делаете, попробуйте несколько и посмотрите, какой из них самый естественный, если у вас есть время. Удачи и счастливого кодирования.

llpp

NUnit всегда был моим любимцем. Однако если вы используете TFS в качестве системы управления версиями, я предлагаю вам придерживаться стека Microsoft.

llpp

Для своего проекта я использовал NUnit и TestDriven.NET с большим успехом. Вы можете либо создать отдельную библиотеку только для размещения тестового кода, либо поместить ее в исполняемый файл или библиотеку. Все зависит от того, хотите ли вы, чтобы ваш производственный код был переплетен с вашим тестовым кодом.

Для внедрения зависимостей я использую NInject в моем текущем проекте и его работа великолепна. Если вы используете инъекцию конструктора, вам не нужно загромождать свой код атрибутом [Inject].

Я не использовал макет библиотеки для моего проекта .NET 2.0, но для другого проекта .NET 3.5 я буду использовать Moq

Обратите внимание, что все это работает с .NET 2.0 и выше. (кроме Moq)

llpp

Я рекомендую следующее:

TestDriven.NET - модульное тестирование приплюсовать для VS, которая полностью интегрирована со всеми основными блок тестирования, включая NUnit, MbUnit и т. д...

Typemock Isolator - издевательский фреймворк для модульного тестирования .Net

NUnit -платформа модульного тестирования с открытым исходным кодом, которая находится в C#.

llppminhojkhonКак я могу модульно тестировать приложения Flex из IDE или сценария сборки?gfffg

В настоящее время я работаю над приложением с интерфейсом, написанным в Adobe Flex 3. Я знаю о FlexUnit , но то, что мне действительно нужно, - это модульный тестовый бегун для Ant/NAnt и бегун, который интегрируется с Flex Builder IDE (AKA Eclipse). Существует ли он вообще?

Кроме того, есть ли какие-либо другие ресурсы о том, как сделать Flex development "the right way", кроме примера микроархитектуры Cairngorm ?

gfffgttaaggflex,eclipse,unit-testing,build-automation,cairngorm,ttaagggfffg

Платформа тестирования dpUint имеет тестовый раннер, построенный с помощью AIR, который может быть интегрирован со сценарием сборки.

Существует также мой комплект автоматизации FlexUnit , который делает более или менее то же самое для FlexUnit. Он имеет макрос Ant, который позволяет запускать тесты как часть сценария Ant, например:

<target name="run-tests" depends="compile-tests">
  <flexunit swf="${build.home}/tests.swf" failonerror="true"/>
</target>
llpp

В моем проекте мы используем Maven для построения как нашего Flex RIA, так и Java-го бэк-энда. Для того, чтобы построить и протестировать приложение Flex мы используем flex-обереги maven плагинов. Они делают большую работу для нас, и я бы очень рекомендовал использовать Maven вместо Ant.

Тем не менее, если вы уже используете Ant, может быть немного сложнее перейти на Maven. Поэтому, если вы находитесь в таком положении, я бы рекомендовал использовать задачи flexunit, доступные здесь: Ant Task

Обе эти библиотеки делают в основном одно и то же, они запускают сгенерированное приложение flexunit test runner mxml в окне и открывают соединение сокета обратно в процесс сборки с помощью JUnit Test runner. Удивительно, но это работает довольно хорошо. Единственная проблема заключается в том, что вы не можете запустить его без головы, поэтому, если вы хотите запустить сборку с сервера CI, вы должны убедиться, что процесс имеет возможность запустить новый windows, иначе он не будет работать.

llpp

О том, как правильно разрабатывать приложения Flex, я бы не стал слишком много смотреть на фреймворк Cairngorm. Он действительно утверждает, что показывает "best practice" и так далее, но я бы сказал, что верно обратное. Он основан на использовании глобальных переменных и других вещах, которых вы должны стараться избегать. Я описал некоторые из этих проблем в своем блоге .

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

llpp

Альтернативой FlexUnit являются инструменты тестирования AsUnit . Существуют версии для actionscript 2 и 3. Он также имеет хорошую интеграцию с Project Sprouts, который является инструментом сборки для Flex и Flash, подобных ant, однако он использует задачи ruby rake и включает отличное управление зависимостями по аналогии с maven.

Однако никакой интеграции IDE, о которой я знаю.

llppminhojkhonВызов shell команд из Rubygfffg

Как вызвать команды shell из программы Ruby? Как же мне тогда получить выходные данные из этих команд обратно в Ruby?

gfffgttaaggruby,shell,interop,ttaagggfffg

Это объяснение основано на комментированном сценарии Ruby от моего друга. Если вы хотите улучшить скрипт, не стесняйтесь обновить его по ссылке.

Во-первых, обратите внимание, что когда Ruby обращается к shell , он обычно вызывает /bin/sh, а не Bash. Некоторый синтаксис Bash не поддерживается /bin/sh во всех системах.

Вот способы выполнения скрипта shell:

cmd = "echo 'hi'" # Sample string that can be used
  1. Kernel#` , обычно называемый backticks- `cmd`

    Это похоже на многие другие языки, включая Bash, PHP и Perl.

    Возвращает результат выполнения команды shell.

    Документы: http://ruby-doc.org/core/Kernel.html#method-i-60

    value = `echo 'hi'`
    value = `#{cmd}`
    
  2. Встроенный синтаксис, %x( cmd )

    После символа x следует разделитель, который может быть любым символом. Если разделитель является одним из символов (, [, { или < , литерал состоит из символов вплоть до соответствующего закрывающего разделителя, с учетом вложенных пар разделителей. Для всех остальных разделителей литерал содержит символы вплоть до следующего вхождения символ-разделитель. Допускается строковая интерполяция #{ ... } .

    Возвращает результат выполнения команды shell, как и обратные клавиши.

    Документы: http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html

    value = %x( echo 'hi' )
    value = %x[ #{cmd} ]
    
  3. Kernel#system

    Выполняет данную команду в подрешетке.

    Возвращает true , если команда была найдена и успешно выполнена, false в противном случае.

    Документы: http://ruby-doc.org/core/Kernel.html#method-i-system

    wasGood = system( "echo 'hi'" )
    wasGood = system( cmd )
    
  4. Kernel#exec

    Заменяет текущий процесс выполнением данной внешней команды.

    Возвращает none, текущий процесс заменяется и никогда не продолжается.

    Документы: http://ruby-doc.org/core/Kernel.html#method-i-exec

    exec( "echo 'hi'" )
    exec( cmd ) # Note: this will never be reached because of the line above
    

Вот вам несколько дополнительных советов: $?, который является тем же самым , что и $CHILD_STATUS, получает доступ к состоянию последней выполненной системой команды, если вы используете backticks, system() или %x{} . Затем можно получить доступ к свойствам exitstatus и pid :

$?.exitstatus

Дополнительные сведения см. В разделе:

llpp

Вот блок-схема, основанная на этом ответе . См. также использование script для эмуляции terminal .

enter image description here

llpp

Мне нравится делать это с помощью литерала %x , что делает его легким (и читаемым!) использовать кавычки в команде, например так:

directorylist = %x[find . -name '*test.rb' | sort]

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

directorylist.each do |filename|
  filename.chomp!
  # work with file
end
llpp

Вот лучшая статья, на мой взгляд, о запуске shell скриптов в Ruby: "6 способов запуска Shell команд в Ruby".

Если вам нужно только получить выходные данные, используйте backticks.

Мне нужны были более продвинутые вещи, такие как STDOUT и STDERR, поэтому я использовал Open4 gem. У вас есть все методы, объясненные там.

llpp

Мой любимый- Open3

  require "open3"

  Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }
llpp

Некоторые вещи, о которых следует подумать при выборе между этими механизмами::

  1. Вы просто хотите stdout или нет также нужен поток stderr? или даже больше отделились друг от друга?
  2. Насколько велик ваш выход? Вы хотите чтобы сохранить весь результат в памяти?
  3. Вы хотите прочитать некоторые из ваших книг вывод, пока подпроцесс еще находится работает?
  4. Вам нужны коды результатов?
  5. Вам нужен объект ruby, который представляет процесс и позволяет вам убить его по первому требованию?

Вам может понадобиться все, что угодно, от простых backticks ( ` ), system() и IO.popen до полноценных Kernel.fork / Kernel.exec с IO.pipe и IO.select .

Вы также можете использовать тайм-ауты в миксе, если выполнение подпроцесса занимает слишком много времени.

К сожалению, от этого очень многое зависит .

llpp

Еще один вариант:

Когда вы:

  • нужен stderr а также stdout
  • can't/won't использовать Open3/Open4 (они выбрасывают исключения в NetBeans на моем Mac, не знаю почему)

Вы можете использовать перенаправление shell:

puts %x[cat bogus.txt].inspect
  => ""

puts %x[cat bogus.txt 2>&1].inspect
  => "cat: bogus.txt: No such file or directory\n"

Синтаксис 2>&1 работает через Linux, Mac и Windows с первых дней MS-DOS.

llpp

Я определенно не эксперт Ruby, но я попробую это сделать:

$ irb 
system "echo Hi"
Hi
=> true

Вы также должны уметь делать такие вещи, как:

cmd = 'ls'
system(cmd)
llpp

Ответы выше уже достаточно велики, но я действительно хочу поделиться следующей краткой статьей: "6 способов запуска команд Shell в Ruby "

В основном, это говорит нам:

Kernel#exec :

exec 'echo "hello $HOSTNAME"'

system и $? :

system 'false' 
puts $?

Кавычки (`):

today = `date`

IO#popen :

IO.popen("date") { |f| puts f.gets }

Open3#popen3 -- stdlib:

require "open3"
stdin, stdout, stderr = Open3.popen3('dc') 

Open4#popen4 -в gem:

require "open4" 
pid, stdin, stdout, stderr = Open4::popen4 "false" # => [26327, #<IO:0x6dff24>, #<IO:0x6dfee8>, #<IO:0x6dfe84>]
llpp

Если вам действительно нужно Bash, то в соответствии с примечанием в ответе "best".

Во-первых, обратите внимание, что когда Ruby обращается к shell , он обычно вызывает /bin/sh, а не Bash. Некоторый синтаксис Bash не поддерживается /bin/sh во всех системах.

Если вам нужно использовать Bash, вставьте bash -c "your Bash-only command" в нужный вызывающий метод.

quick_output = system("ls -la")

quick_bash = system("bash -c 'ls -la'")

Тестировать:

system("echo $SHELL") system('bash -c "echo $SHELL"')

Или если вы запускаете существующий файл скрипта (например, script_output = system("./my_script.sh")) Ruby должен соблюдать shebang, но вы всегда можете использовать system("bash ./my_script.sh") , чтобы убедиться (хотя может быть небольшая накладная от /bin/sh запуска /bin/bash, вы, вероятно, не заметите.

llpp

Вы также можете использовать обратные операторы ( ` ), аналогичные Perl:

directoryListing = `ls /`
puts directoryListing # prints the contents of the root directory

Удобно, если вам нужно что-то простое.

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

llpp

самый простой способ-это, например:

reboot = `init 6`
puts reboot
llpp

Мы можем достичь этого несколькими способами.

Используя Kernel#exec, ничего после выполнения этой команды не происходит:

exec('ls ~')

Использование backticks or %x

`ls ~`
=> "Applications\nDesktop\nDocuments"
%x(ls ~)
=> "Applications\nDesktop\nDocuments"

Используя Kernel#system команды, в случае успеха возвращает true , false , если неудачно и возвращает nil если выполнение команды завершается:

system('ls ~')
=> true
llpp

Используя ответы здесь и связанные в ответе Михая, я собрал функцию, которая отвечает этим требованиям:

  1. Аккуратно захватывает STDOUT и STDERR, поэтому они не "leak", когда мой скрипт запускается из консоли.
  2. Позволяет передавать аргументы в shell как массив, так что нет необходимости беспокоиться об экранировании.
  3. Захватывает состояние выхода команды, чтобы было ясно, когда произошла ошибка.

В качестве бонуса он также вернет STDOUT в тех случаях, когда команда shell успешно завершает работу (0) и ставит что-либо на STDOUT. Таким образом, он отличается от system , который просто возвращает true в таких случаях.

Далее следует код. Конкретная функция- system_quietly :

require 'open3'

class ShellError < StandardError; end

#actual function:
def system_quietly(*cmd)
  exit_status=nil
  err=nil
  out=nil
  Open3.popen3(*cmd) do |stdin, stdout, stderr, wait_thread|
    err = stderr.gets(nil)
    out = stdout.gets(nil)
    [stdin, stdout, stderr].each{|stream| stream.send('close')}
    exit_status = wait_thread.value
  end
  if exit_status.to_i > 0
    err = err.chomp if err
    raise ShellError, err
  elsif out
    return out.chomp
  else
    return true
  end
end

#calling it:
begin
  puts system_quietly('which', 'ruby')
rescue ShellError
  abort "Looks like you don't have the `ruby` command. Odd."
end

#output: => "/Users/me/.rvm/rubies/ruby-1.9.2-p136/bin/ruby"
llpp

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

pid = spawn("tar xf ruby-2.0.0-p195.tar.bz2")
Process.wait pid

pid = spawn(RbConfig.ruby, "-eputs'Hello, world!'")
Process.wait pid

Doc говорит:Этот метод похож на #system , но он не ждет завершения команды.

llpp

Если у вас есть более сложный случай, чем обычный случай (который не может быть обработан с помощью ``), то проверьте Kernel.spawn() здесь . Это, по-видимому, самый generic/full-featured предоставленный запасом Ruby для выполнения внешних команд.

E.g. вы можете использовать его для того чтобы:

  • создание групп процессов (Windows)
  • перенаправление in, out, error на files/each-other.
  • установить env vars, umask
  • смена каталога перед выполнением команды
  • установите лимиты ресурсов для CPU/data/...
  • Сделайте все, что можно сделать с другими вариантами в других ответах, но с большим количеством кода.

Официальная документация ruby имеет достаточно хорошие примеры.

env: hash
  name => val : set the environment variable
  name => nil : unset the environment variable
command...:
  commandline                 : command line string which is passed to the standard shell
  cmdname, arg1, ...          : command name and one or more arguments (no shell)
  [cmdname, argv0], arg1, ... : command name, argv[0] and zero or more arguments (no shell)
options: hash
  clearing environment variables:
    :unsetenv_others => true   : clear environment variables except specified by env
    :unsetenv_others => false  : dont clear (default)
  process group:
    :pgroup => true or 0 : make a new process group
    :pgroup => pgid      : join to specified process group
    :pgroup => nil       : dont change the process group (default)
  create new process group: Windows only
    :new_pgroup => true  : the new process is the root process of a new process group
    :new_pgroup => false : dont create a new process group (default)
  resource limit: resourcename is core, cpu, data, etc.  See Process.setrlimit.
    :rlimit_resourcename => limit
    :rlimit_resourcename => [cur_limit, max_limit]
  current directory:
    :chdir => str
  umask:
    :umask => int
  redirection:
    key:
      FD              : single file descriptor in child process
      [FD, FD, ...]   : multiple file descriptor in child process
    value:
      FD                        : redirect to the file descriptor in parent process
      string                    : redirect to file with open(string, "r" or "w")
      [string]                  : redirect to file with open(string, File::RDONLY)
      [string, open_mode]       : redirect to file with open(string, open_mode, 0644)
      [string, open_mode, perm] : redirect to file with open(string, open_mode, perm)
      [:child, FD]              : redirect to the redirected file descriptor
      :close                    : close the file descriptor in child process
    FD is one of follows
      :in     : the file descriptor 0 which is the standard input
      :out    : the file descriptor 1 which is the standard output
      :err    : the file descriptor 2 which is the standard error
      integer : the file descriptor of specified the integer
      io      : the file descriptor specified as io.fileno
  file descriptor inheritance: close non-redirected non-standard fds (3, 4, 5, ...) or not
    :close_others => false : inherit fds (default for system and exec)
    :close_others => true  : dont inherit (default for spawn and IO.popen)
llpp
  • метод backticks является самым простым для вызова shell команд из ruby. Он возвращает результат выполнения команды shell.

     url_request = 'http://google.com'
     result_of_shell_command = `curl #{url_request}`
    
llpp

Дали команду, например, свойства

require 'open3'

a="attrib"
Open3.popen3(a) do |stdin, stdout, stderr|
  puts stdout.read
end

Я обнаружил, что хотя этот метод не так запоминается, как, например, system ("thecommand") или команда в backticks, это хорошая вещь в этом методе по сравнению с другими методами.. это напр. backticks, похоже, не позволяет мне 'puts' выполнить команду / сохранить команду, которую я хочу выполнить, в переменной, а system("thecommand"), похоже, не позволяет мне получить выходные данные. В то время как этот метод позволяет мне делать обе эти вещи, и он позволяет мне получить доступ к stdin, stdout и stderr независимо.

https://blog.bigbinary.com/2012/10/18/backtick-system-exec-in-ruby.html

http://ruby-doc.org/stdlib-2.4.1/libdoc/open3/rdoc/Open3.html

llpp

Не совсем ответ, но, возможно, кто-то найдет это полезным, и его отношение к этому.

При использовании графического интерфейса TK на Windows, и u нужно вызвать команды shell из rubyw, u всегда будет иметь раздражающее окно cmd, выскакивающее менее чем за секунду.

Чтобы избежать этого вы можете использовать

WIN32OLE.new('Shell.Application').ShellExecute('ipconfig > log.txt','','','open',0)

или

WIN32OLE.new('WScript.Shell').Run('ipconfig > log.txt',0,0)

Оба будут хранить выходные данные ipconfig внутри 'log.txt', но никакой windows не появится.

Вам нужно будет require 'win32ole' внутри вашего скрипта.

system() , exec() и spawn() будут все всплывать это раздражающее окно при использовании TK и rubyw.

llpp

Вот классный скрипт, который я использую в скрипте ruby на OS X (так что я могу запустить скрипт и получить обновление даже после переключения из окна):

cmd = %Q|osascript -e 'display notification "Server was reset" with title "Posted Update"'|
system ( cmd )
llppminhojkhonНабор данных Datatable против gfffg

В настоящее время я использую DataTable для получения результатов из базы данных, которую я могу использовать в своем коде.

Однако многие примеры в интернете показывают использование DataSet вместо этого и доступ к таблице(таблицам) через метод collections.

Есть ли какое-либо преимущество, с точки зрения производительности или иным образом, в использовании DataSets или DataTables в качестве метода хранения результатов SQL?

gfffgttaaggc#,dataset,datatable,ttaagggfffg

Это действительно зависит от типа данных, которые вы приносите обратно. Поскольку DataSet-это (по сути) просто набор объектов DataTable, вы можете возвращать несколько различных наборов данных в один и, следовательно, более управляемый объект.

С точки зрения производительности вы с большей вероятностью получите неэффективность от неоптимизированных запросов, чем от выбора "wrong" конструкции .NET. По крайней мере, таков был мой опыт.

llpp

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

Если вы возвращаете только один результирующий набор, хотя я думаю, что DataTable будет более оптимизирован. Я бы подумал, что должны быть некоторые накладные расходы (конечно, небольшие), чтобы предложить функциональность a DataSet и отслеживать несколько DataTables.

llpp

в 1.x году были вещи, которые DataTables не мог сделать, а DataSets мог (не помню точно, что именно). Все это было изменено в 28 году. Я предполагаю, что именно поэтому многие примеры все еще используют DataSets. DataTables должно быть быстрее, так как они более легкие. Если вы тянете только один результирующий набор, это ваш лучший выбор между ними.

llpp

Одна из особенностей DataSet заключается в том, что если вы можете вызвать несколько операторов select в ваших хранимых процедурах, то DataSet будет иметь один DataTable для каждого.

llpp

Есть некоторые оптимизации, которые можно использовать при заполнении DataTable, например вызов BeginLoadData(), вставка данных, а затем вызов EndLoadData(). Это отключает некоторое внутреннее поведение в пределах DataTable, такое как обслуживание индекса и т. д. Дополнительную информацию смотрите в этой статье .

llpp

Когда вы все равно имеете дело только с одной таблицей, самое большое практическое различие, которое я обнаружил, заключается в том, что DataSet имеет метод "HasChanges", а DataTable-нет. Однако у обоих есть "GetChanges", поэтому вы можете использовать его и проверить для null.

llppminhojkhonСопоставление потоковых данных со структурами данных в C#gfffg

Существует ли способ отображения данных, собранных в потоке или массиве, в структуру данных или наоборот? В C++ это будет просто вопрос приведения указателя на поток в качестве типа данных, который я хочу использовать (или наоборот для обратного) например: in C++

Mystruct * pMyStrct = (Mystruct*)&SomeDataStream;
pMyStrct->Item1 = 25;

int iReadData = pMyStrct->Item2;

очевидно, что способ C++ довольно небезопасен, если вы не уверены в качестве потоковых данных при чтении входящих данных, но для исходящих данных это очень быстро и легко.

gfffgttaaggc#,c++,data-structures,ttaagggfffg

Большинство людей используют сериализацию .NET (есть более быстрый двоичный формат и более медленный форматер XML, они оба зависят от отражения и в определенной степени терпимы к версии)

Однако, если вы хотите самый быстрый (небезопасный) способ - почему бы и нет:

Пишу:

YourStruct o = new YourStruct();
byte[] buffer = new byte[Marshal.SizeOf(typeof(YourStruct))];
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
Marshal.StructureToPtr(o, handle.AddrOfPinnedObject(), false);
handle.Free();

Чтение:

handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
o = (YourStruct)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(YourStruct));
handle.Free();
llpp

В случае, если ответ Любоша хаско был недостаточно небезопасным, существует также действительно небезопасный способ, используя указатели в C#. вот некоторые советы и подводные камни, с которыми я столкнулся:

using System;
using System.Runtime.InteropServices;
using System.IO;
using System.Diagnostics;

// Use LayoutKind.Sequential to prevent the CLR from reordering your fields.
[StructLayout(LayoutKind.Sequential)]
unsafe struct MeshDesc
{
    public byte NameLen;
    // Here fixed means store the array by value, like in C,
    // though C# exposes access to Name as a char*.
    // fixed also requires 'unsafe' on the struct definition.
    public fixed char Name[16];
    // You can include other structs like in C as well.
    public Matrix Transform;
    public uint VertexCount;
    // But not both, you can't store an array of structs.
    //public fixed Vector Vertices[512];
}

[StructLayout(LayoutKind.Sequential)]
unsafe struct Matrix
{
    public fixed float M[16];
}

// This is how you do unions
[StructLayout(LayoutKind.Explicit)]
unsafe struct Vector
{
    [FieldOffset(0)]
    public fixed float Items[16];
    [FieldOffset(0)]
    public float X;
    [FieldOffset(4)]
    public float Y;
    [FieldOffset(8)]
    public float Z;
}

class Program
{
    unsafe static void Main(string[] args)
    {
        var mesh = new MeshDesc();
        var buffer = new byte[Marshal.SizeOf(mesh)];

        // Set where NameLen will be read from.
        buffer[0] = 12;
        // Use Buffer.BlockCopy to raw copy data across arrays of primitives.
        // Note we copy to offset 2 here: char's have alignment of 2, so there is
        // a padding byte after NameLen: just like in C.
        Buffer.BlockCopy("Hello!".ToCharArray(), 0, buffer, 2, 12);

        // Copy data to struct
        Read(buffer, out mesh);

        // Print the Name we wrote above:
        var name = new char[mesh.NameLen];
        // Use Marsal.Copy to copy between arrays and pointers to arrays.
        unsafe { Marshal.Copy((IntPtr)mesh.Name, name, 0, mesh.NameLen); }
        // Note you can also use the String.String(char*) overloads
        Console.WriteLine("Name: " + new string(name));

        // If Erik Myers likes it...
        mesh.VertexCount = 4711;

        // Copy data from struct:
        // MeshDesc is a struct, and is on the stack, so it's
        // memory is effectively pinned by the stack pointer.
        // This means '&' is sufficient to get a pointer.
        Write(&mesh, buffer);

        // Watch for alignment again, and note you have endianess to worry about...
        int vc = buffer[100] | (buffer[101] << 8) | (buffer[102] << 16) | (buffer[103] << 24);
        Console.WriteLine("VertexCount = " + vc);
    }

    unsafe static void Write(MeshDesc* pMesh, byte[] buffer)
    {
        // But byte[] is on the heap, and therefore needs
        // to be flagged as pinned so the GC won't try to move it
        // from under you - this can be done most efficiently with
        // 'fixed', but can also be done with GCHandleType.Pinned.
        fixed (byte* pBuffer = buffer)
            *(MeshDesc*)pBuffer = *pMesh;
    }

    unsafe static void Read(byte[] buffer, out MeshDesc mesh)
    {
        fixed (byte* pBuffer = buffer)
            mesh = *(MeshDesc*)pBuffer;
    }
}
llpp

если его .net с обеих сторон:

думаю, вам следует использовать двоичную сериализацию и отправить результат byte[].

доверие к вашей структуре, чтобы быть полностью блистательной может быть проблемой.

вы будете оплачивать некоторые накладные расходы (как cpu, так и сеть), но будете в безопасности.

llpp

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

Вот код, который я использовал для обобщения десериализации из byte[].

public virtual bool SetMessageBytes(byte[] message)
    {
        MemberInfo[] members = FormatterServices.GetSerializableMembers(this.GetType());
        object[] values = FormatterServices.GetObjectData(this, members);
        int j = 0;

        for (int i = 0; i < members.Length; i++)
        {
            string[] var = members[i].ToString().Split(new char[] { ' ' });
            switch (var[0])
            {
                case "UInt32":
                    values[i] = (UInt32)((message[j] << 24) + (message[j + 1] << 16) + (message[j + 2] << 8) + message[j + 3]);
                    j += 4;
                    break;
                case "UInt16":
                    values[i] = (UInt16)((message[j] << 8) + message[j + 1]);
                    j += 2;
                    break;
                case "Byte":
                    values[i] = (byte)message[j++];
                    break;
                case "UInt32[]":
                    if (values[i] != null)
                    {
                        int len = ((UInt32[])values[i]).Length;
                        byte[] b = new byte[len * 4];
                        Array.Copy(message, j, b, 0, len * 4);
                        Array.Copy(Utilities.ByteArrayToUInt32Array(b), (UInt32[])values[i], len);
                        j += len * 4;
                    }
                    break;
                case "Byte[]":
                    if (values[i] != null)
                    {
                        int len = ((byte[])values[i]).Length;
                        Array.Copy(message, j, (byte[])(values[i]), 0, len);
                        j += len;
                    }
                    break;
                default:
                    throw new Exception("ByteExtractable::SetMessageBytes Unsupported Type: " + var[1] + " is of type " +  var[0]);
            }
        }
        FormatterServices.PopulateObjectMembers(this, members, values);
        return true;
    }
llppminhojkhonASP.NET URL переписываниеgfffg

Как мне переписать URL в ASP.NET?

Я бы хотел, чтобы пользователи могли получить http://www.website.com/users/smith вместо http://www.website.com/?пользователь=Смит

gfffgttaaggasp.net,url,url-rewriting,url-routing,rewrite,ttaagggfffg

Попробуйте управляемый Fusion Url Rewriter и обратный прокси-сервер:

http://urlrewriter.codeplex.com

Правилом для переписывания этого было бы:

# clean up old rules and forward to new URL
RewriteRule ^/?user=(.*)  /users/$1 [NC,R=301]

# rewrite the rule internally
RewriteRule ^/users/(.*)  /?user=$1 [NC,L]
llpp

Microsoft теперь поставляет официальный модуль перезаписи URL для IIS: http://www.iis.net/download/urlrewrite

Он поддерживает большинство типов перезаписи, включая установку переменных сервера и подстановочных знаков.

Он также будет существовать на всех веб-экземплярах Azure из коробки.

llpp

Я использовал httpmodule для url перезаписи из www.urlrewriting.net с большим успехом (хотя я считаю, что гораздо более ранняя, более простая версия)

Если у вас очень мало фактических правил перезаписи, то url сопоставления, встроенные в .NET 2.0, вероятно, являются более простым вариантом, есть несколько таких записей в интернете, 4guysfromrolla one кажется довольно исчерпывающим, но, как вы можете видеть, они не поддерживают сопоставления регулярных выражений, которые, как таковые, оказываются довольно бесполезными в динамической среде (предполагая, что "smith" в вашем примере не является особым случаем, тогда они не будут использовать)

llppminhojkhonКак фильтровать и объединять 2 набора данных в C#gfffg

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

Общий пункт - SKU. Я буду вытаскивать список SKUs из базы данных покупок клиентов,и в таблице загрузки есть список SKUs, связанный с этой загрузкой. Мое намерение, на данный момент, состоит в том, чтобы создать из этого datatable для заполнения GridView .

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

gfffgttaaggc#,.net,ttaagggfffg

До тех пор, пока две базы данных находятся на одном физическом сервере (предполагая MSSQL) и имя пользователя/пароль, используемые в строке подключения, имеют права на оба DBs, вы должны иметь возможность выполнить соединение между двумя базами данных. Пример:

select p.Date,
       p.Amount,
       d.SoftwareName,
       d.DownloadLink
from   PurchaseDB.dbo.Purchases as p
join   ProductDB.dbo.Products as d on d.sku = p.sku
where  p.UserID = 12345
llpp

Почему бы не создать доменный объектно ориентированный подход к этой проблеме:

public class CustomerDownloadInfo
{
    private string sku;
    private readonly ICustomer customer;

    public CustomerDownloadInfo(ICustomer Customer){
        customer = Customer;
    }

    public void AttachSku(string Sku){
        sku = Sku;
    }

    public string Sku{
        get { return sku; }
    }

    public string Link{
        get{    
            // etc... etc...          
        }
    }
}

Существует миллион вариантов этого, но как только вы соберете эту информацию, не будет ли проще представить ее?

llpp

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

llppminhojkhonДобавление пользовательского тега для проверки Visual Studiogfffg

Как я могу добавить правила в Visual Studio (2005 и выше) для проверки свойства markup (HTML) для собственных элементов управления поставщика?

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

gfffgttaaggvisual-studio,ttaagggfffg

Щелкните правой кнопкой мыши на исходном виде страницы HTML / ASP и выберите "Formatting and Validation".

  1. Нажмите кнопку "Tag Specific Options".
  2. Разверните "Client HTML Tags" и выберите заголовок.
  3. Нажмите кнопку "New Tag...".
  4. И просто заполните его!

Я хотел бы также добавить пользовательские значения CSS.

llppminhojkhonКак внести код обратно в проект с открытым исходным кодом?gfffg

Если вы следуете проекту с открытым исходным кодом и хотите внести изменения в код, что вам нужно сделать?

gfffgttaagglanguage-agnostic,open-source,contribute,ttaagggfffg

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

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

llpp

Лучший способ сделать это-представиться так: "Привет, вот ошибка/функция, а вот патч, который исправляет/реализует ее."

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

llpp

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

  • Объявите о себе любым подходящим для проекта способом: email, список рассылки, форум и т. д
  • Посмотрите, есть ли ваша идея уже в работе. Если это так, может быть, попытаться помочь, а не дублировать усилия.
  • Узнайте предпочтительный способ отправки кода
  • Обязательно следуйте стилям кодирования, используемым в проекте. (Если вы решите преобразовать все вкладки в пробелы, они не смогут легко объединить ваши изменения в свою систему управления версиями и, скорее всего, проигнорируют ваше представление.)
llpp

Как уже говорилось на предыдущих плакатах, это дело проекта. Вы обнаружите, что некоторые из них более открыты для перемен, чем другие. С механической точки зрения вам нужно будет посмотреть, используют ли они SVN (например, в коде google) или CVS (например, в sourceforge) и определить, используют ли они патч или какой-то другой метод.

Хороший пример процедуры, которую вам может понадобиться использовать, можно увидеть на сайте gimp: http://www.gimp.org/bugs/howtos/submit-patch.html обратите внимание на их использование Bugzilla, patch и CVS

llpp

Есть еще пара вещей, которые нужно иметь в виду:

  • Убедитесь, что у вас действительно есть код, который вы хотите вернуть, а не ваш работодатель или клиент, для которого вы внесли изменения. Проверьте свой трудовой договор или договор об оказании услуг, если есть вероятность, что вы находитесь в такой ситуации.

  • Исследуйте, существует ли процесс присвоения интеллектуальной собственности, который разработчики предпочитают проходить. В наши дни многие проекты с открытым исходным кодом имеют такие назначения, так что все права на код в проекте могут принадлежать самому проекту и/или его спонсору.

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

llpp

Раньше такие вещи были простыми.

Там был список рассылки для пользователей и один для разработчиков. Если вы видите проблему и можете исправить ее, исправьте ее, а затем запустите патч Ларри Уолла и отправьте полученный патч в список разработчиков с быстрым объяснением того, что он делает. Как правило, разработчик с доступом на запись к CVS (или в реальные старые времена, на чьей дискете находился проект;)) проверял бы все, и если ваш патч делает то, что он говорит на tin, и не нарушает ничего другого, он попадает в собственно дерево исходных текстов.

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

llpp

Если вы ищете способы принять участие в меньшем масштабе (возможно, чтобы работать ваш путь вверх) OpenHatch имеет поисковую базу данных ошибок (отсортированных по language/framework), а также отличный учебник для начала работы.

Другой способ начать-это CodeTriage , который имеет GitHub репозиториев, которые ищут помощь в устранении открытых проблем, которые также организованы по языку.

llpp

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

Простое написание вашего улучшенного кода, а затем передача его им может привести к тому, что ваш код будет отклонен.

llpp

Общайтесь в чате в IRC или просматривайте группы новостей, если они у вас есть. дайте о себе знать. Возможно, Вам потребуется отправить патчи в группу новостей, прежде чем вы получите учетную запись для отправки самостоятельно.

Ознакомьтесь со стандартами кодирования, типами патчей (например, unified diff) и получите копию их CVS или SVN, если они разрешают анонимный доступ.

llpp

Это зависит от проекта, как и где он размещается. Самое лучшее-найти контакт и email их или посмотреть, есть ли список рассылки разработчиков.

llppminhojkhonКак я могу пересечь коллекцию в классическом ASP?gfffg

Я хочу быть в состоянии сделать это:

For Each thing In things
End For

КЛАССИЧЕСКИЙ ASP-NOT .NET!

gfffgttaaggasp-classic,vbscript,ttaagggfffg

Что-то вроде этого?

dim cars(2),x
cars(0)="Volvo"
cars(1)="Saab"
cars(2)="BMW"

For Each x in cars
  response.write(x & "<br />")
Next

Смотрите www.w3schools.com .

Если вы хотите связать ключи и значения используйте вместо этого объект справочника :

Dim objDictionary
Set objDictionary = CreateObject("Scripting.Dictionary")
objDictionary.Add "Name", "Scott"
objDictionary.Add "Age", "20"
if objDictionary.Exists("Name") then
    ' Do something
else
    ' Do something else 
end if
llpp

Все ваши [вещи] должны быть написаны вне VBScript.

В VB6 вы можете написать пользовательский класс коллекции, затем вам нужно будет скомпилироваться в ActiveX DLL и зарегистрировать его на своем webserver, чтобы получить к нему доступ.

llpp

Самое близкое, что вы получите, - это использование словаря (как упоминалось Пацификой)

Dim objDictionary
Set objDictionary = CreateObject("Scripting.Dictionary")
objDictionary.CompareMode = vbTextCompare 'makes the keys case insensitive'
objDictionary.Add "Name", "Scott"
objDictionary.Add "Age", "20"

Но я перелистываю свои словари как коллекцию

For Each Entry In objDictionary
  Response.write objDictionary(Entry) & "<br />"
Next

Таким образом вы можете пройтись по всему словарю выписывая значения которые будут выглядеть следующим образом:

Scott
20

Вы также можете сделать это

For Each Entry In objDictionary
  Response.write Entry & ": " & objDictionary(Entry) & "<br />"
Next

Что бы произвести

 Name: Scott
 Age: 20
llpp

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

Class MyCollection
    Public Property Get Items
        Items = ReturnItemsAsAnArray()
    End Property
    ...
End Class

Повторять как:

Set things = New MyCollection
For Each thing in things.Items
    ...
Next
llpp

Как сказал Бретт, лучше использовать компонент vb для создания коллекций. Объекты словаря не очень часто используются в ASP, если только для конкретных приложений, основанных на потребности.

llpp

Будьте VERY осторожны при использовании объекта VB Script Dictionary!
Просто откройте для себя эту вещь " autovivication ", родную для этого объекта: http://en.wikipedia.org/wiki/Autovivification

Поэтому, когда вам нужно сравнить значения, NEVER использует логическое сравнение, например:
If objDic.Item("varName") <> "" Then ...
Это автоматически добавит ключ " varName " в словарь (если он не существует, с пустым значением) , чтобы продолжить вычисление логического выражения.

При необходимости используйте вместо него If objDic.Exists("varName") .

Просто проведите несколько дней, стуча по стенам, с этой "функцией" Mcrosoft...
vbscript-dictionary-object-creating-a-key-which-never-existed-but-present-in-another-object

llppminhojkhonASP.NET Отображение Номера Редакции SVNgfffg

Я вижу в нижнем колонтитуле переполнения стека, что отображается номер ревизии SVN. Автоматизировано ли это, и если да, то как это можно реализовать в ASP.NET?

(Решения на других языках приемлемы)

gfffgttaaggasp.net,svn,ttaagggfffg

Убедитесь, что в файле есть svn:keywords "Rev Id", а затем поместите $Rev$ где-то там.

Смотрите этот вопрос и ответы на него .

llpp

Поиск выглядит как "OR" вместо "AND" :-( если вы выполняете поиск по ASP.NET SVN в строке поиска, вы не найдете его на странице 6 или около того.

он определенно должен получить некоторую доработку.

llpp

в нашей настройке непрерывной интеграции мы используем SVNRevisionLabeller и передаем переменные из этого в MSBuild для использования при создании скомпилированного сайта dll. Затем он становится доступным для .NET, используя GetCurrentAssembly() в окончательной сборке.

llpp

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

render :text => `svn info #{RAILS_ROOT}`

(это эквивалентно Process.Start( "svn info..." ), если вы знакомы только с .net)

Если мне интересно, если парень, который управляет серверами, недавно обновил сайт, я могу нажать эту URL и посмотреть

llppminhojkhonminhojkhonОтслеживание состояния с помощью ASP.NET AJAX / ICallbackEventHandlergfffg

У меня есть проблема с поддержанием состояния на странице ASP.NET AJAX. Короткая версия: мне нужен какой-то способ обновить страницу ViewState после асинхронного обратного вызова, чтобы отразить любые изменения состояния сервера, сделанные во время асинхронного вызова.

Это, кажется, общая проблема, но я опишу свой сценарий, чтобы помочь объяснить:

У меня есть сетчатый элемент управления, который имеет некоторые улучшения JavaScript, а именно возможность перетаскивать столбцы и строки. Когда столбец или строка перемещаются в новое положение, вызывается метод AJAX для уведомления серверного элемента управления и запуска соответствующего события на стороне сервера ("OnColumnMoved" или "OnRowMoved").

ASP.NET AJAX вызовов, по умолчанию, отправить всю страницу в качестве запроса. Таким образом, страница проходит полный жизненный цикл, viewstate сохраняется и состояние элемента управления восстанавливается до вызова метода RaiseCallbackEvent.

Однако, поскольку вызов AJAX не обновляет страницу, ViewState отражает исходное состояние элемента управления, даже после перемещения столбца или строки. Таким образом, во второй раз, когда происходит действие на стороне клиента, запрос AJAX отправляется на сервер, а элемент управления page & снова создается для отражения первого состояния элемента управления, а не состояния после перемещения первого столбца или строки.

Эта проблема имеет много последствий. Например, если у нас есть действие client-side/AJAX для добавления нового элемента в сетку, а затем строка перетаскивается, сетка строится на стороне сервера с одним элементом меньше, чем на стороне клиента.

И, наконец, & наиболее серьезно для моего конкретного примера, фактический объект источника данных, на который мы действуем, хранится на странице ViewState. Это было проектное решение, позволяющее сохранить статическую копию управляемых данных, которая может быть либо зафиксирована в DB после многих манипуляций, либо отброшена, если пользователь отступит. Это очень трудно изменить.

Итак, опять же, мне нужен способ обновления страницы ViewState при обратном вызове после запуска метода AJAX.

gfffgttaaggasp.net,ajax,asp.net-ajax,viewstate,ttaagggfffg

Проверьте эту запись в блоге: настройка ICallbackEventHandler и Viewstate . Автор, кажется, обращается к той самой ситуации, которую вы испытываете:

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

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

llpp

Если вы все равно уже перетасовали ViewState, вы можете также использовать UpdatePanel. Его частичная обратная связь автоматически обновит страницу ViewState.

llpp

Я действительно нашел обе ссылки, которые вы предоставили, но, как уже отмечалось, они просто описывают проблему, а не решают ее. Автор сообщения в блоге предлагает обходной путь с помощью другого поставщика ViewState, но, к сожалению, это не возможность в этом case...I действительно нужно оставить детали ViewState в покое и просто зацепиться за то, что делается out-of-the-box.

llpp

Я нашел довольно элегантное решение с Telerik RadAjaxManager . Это работает довольно хорошо, по сути, вы регистрируете каждый элемент управления, который может вызвать обратную передачу, а затем регистрируете каждый элемент управления, который должен быть повторно нарисован после того, как эта обратная передача выполняется асинхронно. RadAjaxManager обновит DOM после асинхронной обратной передачи и перепишет ViewState и все затронутые элементы управления. После того, как я заглянул в отражатель, он выглядит немного клудным под капотом, но он подходит для моих целей.

llpp

Я не понимаю, почему вы используете пользовательский элемент управления для этого, когда встроенный ASP.NET AJAX UpdatePanel делает то же самое.

Это просто добавляет больше сложности, дает вам меньше поддержки и затрудняет другим работу над вашим приложением.

llppminhojkhonКак включить номера строк по умолчанию в TextWrangler на Mac?gfffg

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

gfffgttaaggmacos,textwrangler,ttaagggfffg

Перейдите в раздел TextWrangler > настройки.

Выберите пункт отображение состояния текста на панели категорий,затем установите флажок "Show line numbers" и закройте настройки. Теперь он должен быть включен по умолчанию при открытии существующих документов.

llppminhojkhonЧто является лучшим способом, чтобы перебрать массив в классическом ASP VBScript?gfffg

В приведенном ниже коде

For i = LBound(arr) To UBound(arr)

Какой смысл спрашивать, используя LBound ? Конечно, это всегда 0.

gfffgttaaggarrays,asp-classic,vbscript,ttaagggfffg

Почему бы не использовать For Each ? Таким образом, вам не нужно беспокоиться о том, что такое LBound и UBound .

Dim x, y, z
x = Array(1, 2, 3)

For Each y In x
    z = DoSomethingWith(y)
Next
llpp

Есть веская причина не использовать For i = LBound(arr) To UBound(arr)

dim arr(10) выделяет одиннадцать членов массива, от 0 до 10 (предполагая, что база параметров по умолчанию VB6).

Многие программисты VB6 предполагают, что массив основан на одном элементе, и никогда не используют выделенный arr(0) . Мы можем удалить потенциальный источник ошибок, используя For i = 1 To UBound(arr) или For i = 0 To UBound(arr), потому что тогда становится ясно, используется ли arr(0) .

For each создает копию каждого элемента массива, а не указатель.

Здесь есть две проблемы.

  1. Когда мы пытаемся присвоить значение элементу массива, это не отражается на оригинале. Этот код присваивает переменной i значение 47, но не влияет на элементы arr .

    arr = Array(3,4,8)
    for each i in arr
         i = 47
    next i
    Response.Write arr(0) '- returns 3, not 47

  2. Мы не знаем индекс элемента массива в A for each, и нам не гарантируется последовательность элементов (хотя это, кажется, в порядке вещей.)

llpp

LBound не всегда может быть 0.

Хотя невозможно создать массив, который имеет что-либо, кроме нижней границы 0 в VBScript, все же можно получить массив вариантов из компонента COM, который, возможно, указал другой LBound .

Тем не менее, я никогда не встречал никого, кто сделал бы что-то подобное.

llpp

Вероятно, это происходит от VB6. Потому что с помощью оператора Option Base в VB6 вы можете изменить нижнюю границу массивов следующим образом:

Option Base 1

Кроме того, в VB6 вы можете изменить нижнюю границу определенного массива следующим образом:

Dim myArray(4 To 42) As String
llpp

Я всегда использовал для каждого из них...

llppminhojkhonКак на вкладке фокус на выпадающее поле в Mac OSXgfffg

В Windows, в любой форме windows или веб-браузере, вы можете использовать кнопку tab для переключения фокуса по всем полям формы.

Он остановится на текстовых полях, радиокнопках, флажках, выпадающих меню и т. д.

Однако в Mac OSX tab пропускает выпадающие меню. Есть ли способ изменить это поведение или получить доступ к вышеупомянутым элементам без использования мыши?

gfffgttaaggmacos,mouse,keyboard-shortcuts,ttaagggfffg

Перейдите в раздел Системные настройки > Клавиатура и мышь, затем выберите сочетания клавиш. В нижней части экрана убедитесь, что для полного доступа к клавиатуре установлено значение "All controls". Я уже давно его не включал но думаю это все что тебе нужно сделать

llpp

Меню Apple > Системные Настройки > Клавиатура & Мышь > Сочетания Клавиш:

Измените переключатель внизу с "Text boxes and lists only" на "All controls."

Правка: Черт Возьми. Мы ведь здесь очень быстрая группа, не так ли? :-)

llpp

Я обнаружил, что мне также нужно установить accessibility.tabfocus на 7 в Firefox about:config .

llpp

Это в Системных настройках - этот пост в блоге показывает, где находится настройка.



Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться