Как декодировать экранированные символы Unicode (\ u30c1 - & gt; チ)? [Дубликат]

Другим случаем, когда NullReferenceExceptions может случиться, является (неправильное) использование оператора as :

class Book {
    public string Name { get; set; }
}
class Car { }

Car mycar = new Car();
Book mybook = mycar as Book;   // Incompatible conversion --> mybook = null

Console.WriteLine(mybook.Name);   // NullReferenceException

Здесь Book и Car являются несовместимыми типами; a Car не может быть преобразован / передан в Book. Когда этот сбой завершается неудачно, as возвращает null. Используя mybook после этого, вы вызываете NullReferenceException.

В общем случае вы должны использовать cast или as, как показано ниже:

Если вы ожидаете преобразования типа в всегда преуспевает (т. е. вы знаете, какой объект должен быть впереди времени), тогда вы должны использовать cast:

ComicBook cb = (ComicBook)specificBook;

Если вы не уверены в типе, но хотите попробовать , чтобы использовать его как определенный тип, затем используйте as:

ComicBook cb = specificBook as ComicBook;
if (cb != null) {
   // ...
}

3
задан kseen 15 March 2012 в 05:12
поделиться

2 ответа

Вы можете использовать блок DBXJSON , который включен в Delphi 2010

uses
 DBXJSON;

const
JsonUt8  ='"\u041f\u043e\u0438\u0441\u043a \u043f\u043e \u0444\u0430\u043c\u0438\u043b\u0438\u0438, \u0438\u043c\u0435\u043d\u0438 (\u043e\u0442\u0447\u0435\u0441\u0442\u0432\u0443"';

procedure TForm59.Button1Click(Sender: TObject);
var
  LJSONValue: TJSONValue;
begin
  LJSONValue:=TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(JsonUt8),0);
  Edit1.Text:=LJSONValue.ToString;
end;

enter image description here [/g1]

13
ответ дан RRUZ 28 August 2018 в 17:04
поделиться

ОК, ребята, вот полный код, который поможет мне справиться с этой проблемой:

function Unescape(const s: AnsiString): string;
var
  i: Integer;
  j: Integer;
  c: Integer;
begin
  // Make result at least large enough. This prevents too many reallocs
  SetLength(Result, Length(s));
  i := 1;
  j := 1;
  while i <= Length(s) do begin
    if s[i] = '\' then begin
      if i < Length(s) then begin
        // escaped backslash?
        if s[i + 1] = '\' then begin
          Result[j] := '\';
          inc(i, 2);
        end
        // convert hex number to WideChar
        else if (s[i + 1] = 'u') and (i + 1 + 4 <= Length(s))
                and TryStrToInt('$' + string(Copy(s, i + 2, 4)), c) then begin
          inc(i, 6);
          Result[j] := WideChar(c);
        end else begin
          raise Exception.CreateFmt('Invalid code at position %d', [i]);
        end;
      end else begin
        raise Exception.Create('Unexpected end of string');
      end;
    end else begin
      Result[j] := WideChar(s[i]);
      inc(i);
    end;
    inc(j);
  end;

  // Trim result in case we reserved too much space
  SetLength(Result, j - 1);
end;

const
  NormalizationC = 1;

function NormalizeString(NormForm: Integer; lpSrcString: PWideChar; cwSrcLength: Integer;
 lpDstString: PWideChar; cwDstLength: Integer): Integer; stdcall; external 'Normaliz.dll';

function Normalize(const s: string): string;
var
  newLength: integer;
begin
  // in NormalizationC mode the result string won't grow longer than the input string
  SetLength(Result, Length(s));
  newLength := NormalizeString(NormalizationC, PChar(s), Length(s), PChar(Result), Length(Result));
  SetLength(Result, newLength);
end;

function UnescapeAndNormalize(const s: AnsiString): string;
begin
  Result := Normalize(Unescape(s));
end;

Код украден из этого ответа

0
ответ дан Community 28 August 2018 в 17:04
поделиться
Другие вопросы по тегам:

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