Реализация по умолчанию компилятора C# добавления обработчика событий звонит Delegate.Combine
, в то время как удаление обработчика событий звонит Delegate.Remove
:
Fire = (MyDelegate) Delegate.Remove(Fire, new MyDelegate(Program.OnFire));
реализация Платформы Delegate.Remove
не смотрит эти MyDelegate
сам объект, но в методе делегат обращается к (Program.OnFire
). Таким образом совершенно безопасно создать новое MyDelegate
объект при отмене подписки существующего обработчика событий. Из-за этого компилятор C# позволяет Вам использовать синтаксис стенографии (который генерирует точно тот же код негласно) при добавлении/удалении обработчиков событий: можно опустить new MyDelegate
часть:
Fire += OnFire;
Fire -= OnFire;
, Когда последний делегат удален из обработчика событий, Delegate.Remove
пустой указатель возвратов. Как Вы узнали, важно проверить событие по пустому указателю прежде, чем повысить его:
MyDelegate handler = Fire;
if (handler != null)
handler("Hello 3");
Это присвоено временной локальной переменной для защиты от возможного состояния состязания с отказывающимися от подписки обработчиками событий на других потоках. (См. мое сообщение в блоге для получения дополнительной информации о потокобезопасности присвоения обработчика событий к локальной переменной.) Другой способ защитить от этой проблемы состоит в том, чтобы создать пустого делегата, который всегда подписывается; в то время как это использует немного больше памяти, обработчик событий никогда не может быть пустым (и код может быть более простым):
public static event MyDelegate Fire = delegate { };
Есть несколько способов сделать это. Вы можете разделить строку на пробел, а затем передать ее в TStringList. Затем вы можете использовать свойство Value [String] TStringList для получения значения заданного имени.
Для этого замените все пробелы запятыми:
newString := StringReplace(oldString, ' ', ',', [rfReplaceAll]);
Затем импортируйте результат в TStringList:
var
MyStringList : TStringList;
begin
MyStringList := TStringList.Create;
try
MyStringList.CommaText := StringReplace(oldString, ' ', ',', [rfReplaceAll]);
Result := MyStringList.Values['email'];
finally
MyStringList.Free;
end;
end;
Это даст вам значение электронной почты. Затем вам необходимо разделить строку по символу «@», что является относительно тривиальным упражнением. Конечно, это работает только в том случае, если пробелы действительно являются разделителем между полями.
В качестве альтернативы вы можете использовать регулярное выражение, но Delphi не поддерживает его изначально (вам понадобится библиотека регулярных выражений - см. здесь )
*** Smasher заметил (D2006 +) разделитель / текст с разделителями, который будет выглядеть примерно так:
MyStringList.Delimiter := ' ';
MyStringList.DelimitedText := oldString;
Result := MyStringList.Values['email'];
Следующий код работает, только если значения не содержат пробелов:
uses
StrUtils, Classes;
....
function GetPropertyValue (const PropertyName : String; const InputString : String) : String;
var
StringList : TStringList;
Str : String;
begin
Result := '';
StringList := TStringList.Create;
try
StringList.Delimiter := ' ';
StringList.DelimitedText := InputString;
for Str in StringList do
if StartsText (PropertyName + '=', Str) then
Result := RightStr (Str, Length (Str) - Length (PropertyName) - 1);
finally
FreeAndNil (StringList);
end;
end;
Еще одна идея, вы также можете использовать PosEx (StrUtils) с текстом StringList:
function ExtractMyString(SrcStr, FromStr, ToStr: string): string;
var
posBeg, posEnd: integer;
begin
Result := '';
posBeg := Pos(FromStr, SrcStr) + Length(FromStr);
posEnd := PosEx(ToStr, SrcStr, posBeg);
if (posBeg > 0) and (posEnd > posBeg) then
Result := Copy(SrcStr, posBeg, posEnd-posBeg);
end;
Использование:
ExtractMyString(StringList.Text, 'email=', ' lots=');
Конечно, это будет работать только в том случае, если исходная строка всегда форматируется одинаково , будет удобно для извлечения других данных по мере необходимости.
Моя идея:
предполагая, что строка содержится в переменной 's', а 'tmp' является другой строковой переменной,
i:= pos ('email=', s);
tmp:= '';
inc (i);
while s[i] <> ' ' do
begin
tmp:= tmp + s[i];
inc (i);
end;
'tmp' будет содержать адрес
Разделите строку на массив строк, используя '=' в качестве разделителя, тогда у вас будет массив в следующем порядке: 'Ключ', затем 'Значение', вы можете затем зациклить путем поиска ключа «email» просто добавьте 1 к индексу массива, чтобы получить значение. Но это могло произойти по-разному (например, кто-то вводит '=' как символ) или в поле значения есть пустые строки