C#: событие с explicity добавляет/удаляет! = типичное событие?

Вы можете реализовать свой OTF шрифт, используя @ font-face, например:

@font-face {
    font-family: GraublauWeb;
    src: url("path/GraublauWeb.otf") format("opentype");
}

@font-face {
    font-family: GraublauWeb;
    font-weight: bold;
    src: url("path/GraublauWebBold.otf") format("opentype");
}

Однако, если вы хотите поддерживать широкий спектр современных браузеров , я бы порекомендовал вам: переключитесь на WOFF и TTF типы шрифтов. Тип WOFF реализован каждым основным настольным браузером, а тип TTF является запасным вариантом для старых браузеров Safari, Android и iOS. Если ваш шрифт бесплатный, вы можете конвертировать его, например, с помощью onlinefontconverter .

@font-face {
    font-family: GraublauWeb;
    src: url("path/GraublauWebBold.woff") format("woff"), url("path/GraublauWebBold.ttf")  format("truetype");
}

Если вы хотите поддерживать почти все браузеры, которые все еще существуют (больше не нужно, IMHO), вы должны добавить еще несколько типов шрифтов, например:

@font-face {
    font-family: GraublauWeb;
    src: url("webfont.eot"); /* IE9 Compat Modes */
    src: url("webfont.eot?#iefix") format("embedded-opentype"), /* IE6-IE8 */
         url("webfont.woff") format("woff"), /* Modern Browsers */
         url("webfont.ttf")  format("truetype"), /* Safari, Android, iOS */
         url("webfont.svg#svgFontName") format("svg"); /* Legacy iOS */
}

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

@ Поддержка браузера font-face

Поддержка браузера EOT

Поддержка браузера WOFF

Поддержка браузера TTF

Поддержка браузера SVG-шрифтов

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

42
задан John Saunders 13 February 2010 в 23:33
поделиться

3 ответа

Потому что вы можете это сделать (это не реальный образец, но он «работает»):

private EventHandler _explicitEvent_A;
private EventHandler _explicitEvent_B;
private bool flag;
public event EventHandler ExplicitEvent {
   add {
         if ( flag = !flag ) { _explicitEvent_A += value; /* or do anything else */ }
         else { _explicitEvent_B += value; /* or do anything else */ }
   } 
   remove {
         if ( flag = !flag ) { _explicitEvent_A -= value; /* or do anything else */ }
         else { _explicitEvent_B -= value; /* or do anything else */ }
   }
}

Как компилятор может узнать, что он должен делать с ExplicitEvent.RaiseEvent () ; "? Ответ: Не может.

The "ExplicitEvent.RaiseEvent ();" является только синтаксическим сахаром, который можно предсказать, только если событие реализовано неявно.

37
ответ дан 26 November 2019 в 23:33
поделиться

Когда вы создаете «подобное поле» событие, например:

public event EventHandler Foo;

компилятор генерирует поле и событие. В исходном коде класса, который объявляет событие, каждый раз, когда вы обращаетесь к Foo , компилятор понимает, что вы имеете в виду поле . Однако это поле является частным, поэтому каждый раз, когда вы обращаетесь к Foo из других классов, оно ссылается на событие (и, следовательно, на код добавления / удаления).

Если вы объявите свой собственный явный код добавления / удаления, вы не получите автоматически сгенерированное поле. Итак, у вас есть только событие, и вы не можете вызвать событие непосредственно в C # - вы можете вызвать только экземпляр делегата. Событие не является экземпляром делегата, это просто пара добавления / удаления.

Теперь ваш код содержит следующее:

public EventHandler TypicalEvent;

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

См. Мою статью о событиях и делегатах для получения дополнительной информации.

t объявление события вообще - оно объявляло общедоступное поле типа делегата EventHandler . Любой может вызвать это, потому что значение - это просто экземпляр делегата. Важно понимать разницу между полем и событием. Вы никогда не должны писать такой код, так же как я уверен, что у вас обычно нет общедоступных полей других типов, таких как string и int . К сожалению, это простая опечатка, и ее относительно сложно исправить. Вы могли бы заметить это, только заметив, что компилятор позволяет вам назначать или использовать значение из другого класса.

См. Мою статью о событиях и делегатах для получения дополнительной информации.

t объявление события вообще - оно объявляло общедоступное поле типа делегата EventHandler . Любой может вызвать это, потому что значение - это просто экземпляр делегата. Важно понимать разницу между полем и событием. Вы никогда не должны писать такой код, так же как я уверен, что у вас обычно нет общедоступных полей других типов, таких как string и int . К сожалению, это простая опечатка, и ее относительно сложно исправить. Вы могли бы заметить это, только заметив, что компилятор позволяет вам назначать или использовать значение из другого класса.

См. Мою статью о событиях и делегатах для получения дополнительной информации.

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

См. Мою статью о событиях и делегатах для получения дополнительной информации.

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

См. Мою статью о событиях и делегатах для получения дополнительной информации.

51
ответ дан 26 November 2019 в 23:33
поделиться

"Простое" объявление для TypicalEvent позволяет компилятору обмануть себя. Он создает запись метаданных события, добавляет и удаляет методы и поле поддержки. Когда ваш код ссылается на TypicalEvent, компилятор переводит его в ссылку на резервное поле; когда внешний код ссылается на TypicalEvent (с использованием + = и - =), компилятор переводит его в ссылку на метод добавления или удаления.

«Явное» объявление обходит эту уловку компилятора. Вы указываете методы добавления и удаления и поле поддержки: действительно, как указывает TcKs, может даже не быть поля поддержки (это обычная причина использования явной формы: см., Например, события в System.Windows.Forms.Control). Поэтому компилятор больше не может спокойно переводить ссылку на TypicalEvent в ссылку на резервное поле: если вы хотите, чтобы резервное поле, фактический объект делегата, вы должны напрямую ссылаться на резервное поле:

_explicitEvent.RaiseEvent()
1
ответ дан 26 November 2019 в 23:33
поделиться
Другие вопросы по тегам:

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