Как знать, какой тип является var?

Facebook больше ни при каких обстоятельствах не делает реальный идентификатор Facebook для пользователя доступным через API.

Если вы запрашиваете (и одобрены) разрешение user_link, URL-адреса https://www.facebook.com/ будут включены. Вам по-прежнему не разрешается пытаться преобразовать эти ссылки в базовый идентификатор, но вы можете использовать их в своем пользовательском интерфейсе или посетить страницу пользователя.

https://developers.facebook.com/docs/facebook-login/permissions/#reference-user_link

10
задан Cesar Romero 16 February 2009 в 18:25
поделиться

2 ответа

Не то, чтобы я знаю о. Можно получить RTTI (информация о Типе выполнения) на опубликованных свойствах класса, но не для "нормальных" переменных как строки и целые числа и т.д. Информация просто не там.

Кроме того, единственный способ, которым Вы могли передать var, не передавая тип, состоит в том, чтобы использовать любого универсальный параметр TObject, универсальный тип (D2008, как в), или как невведенный параметр. Я не могу думать о другом способе передать его, который даже скомпилировал бы.

2
ответ дан 3 December 2019 в 14:54
поделиться

Нет.

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

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

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

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

Если Вы хотите передать произвольный адрес функции и иметь ту функцию, обнаруживают информацию о типе для себя, Вам не повезло. Необходимо будет вместо этого передать PTypeInfo оцените как дополнительный параметр. Это - то, что делают все встроенные функции Delphi. Например, когда Вы звоните New на переменной указателя компилятор вставляет дополнительный параметр, который содержит PTypeInfo значение для типа Вы выделяете. Когда Вы звоните SetLength на динамическом массиве компилятор вставляет a PTypeInfo значение для типа массива.

Ответ, который Вы дали, предполагает поиск чего-то другого, чем, что Вы попросили. Учитывая Ваш вопрос, я думал, что Вы искали гипотетическую функцию, которая могла удовлетворить этот код:

var
  S: string;
  Instance: IObjectType;
  Obj: TDBGrid;
  Info: PTypeInfo;
begin
  Info:= GetVariableTypeInfo(@S);
  Assert(Info = TypeInfo(string));

  Info:= GetVariableTypeInfo(@Instance);
  Assert(Info = TypeInfo(IObjectType));

  Info:= GetVariableTypeInfo(@Obj);
  Assert(Info = TypeInfo(TDBGrid));
end;

Давайте использовать IsClass и IsObject функции от JCL для создания той функции:

function GetVariableTypeInfo(pvar: Pointer): PTypeInfo;
begin
  if not Assigned(pvar) then
    Result := nil
  else if IsClass(PPointer(pvar)^) then
    Result := PClass(pvar).ClassInfo
  else if IsObject(PPointer(pvar)^) then
    Result := PObject(pvar).ClassInfo
  else
    raise EUnknownResult.Create;
end;

Это, очевидно, не будет работать на S или Instance выше, но позволяют нам видеть то, что происходит с Obj:

Info := GetVariableTypeInfo(@Obj);

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

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

// This code will yield no assertion failures.
var
  p: Pointer;
  o: TObject;
  a: array of Integer;
begin
  p := TDBGrid;
  Assert(IsClass(p));

  p := TForm.Create(nil);
  Assert(IsObject(p));

  // So far, so good. Works just as expected.
  // Now things get interesting:

  Pointer(a) := p;
  Assert(IsObject(a));
  Pointer(a) := nil;
  // A dynamic array is an object? Hmm.

  o := nil;
  try
    IsObject(o);
    Assert(False);
  except
    on e: TObject do
      Assert(e is EAccessViolation);
  end;
  // The variable is clearly a TObject, but since it
  // doesn't hold a reference to an object, IsObject
  // can't check whether its class field looks like
  // a valid class reference.
end;

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

Кроме того, Вы сказали, что все, что Вы знаете о переменной, является ее адресом. Функции, которые Вы нашли, не берут адрес переменной. Они принимают значение переменной. Вот демонстрация:

var
  c: TClass;
begin
  c := TDBGrid;
  Assert(IsClass(c));
  Assert(not IsClass(@c)); // Address of variable
  Assert(IsObject(@c)); // Address of variable is an object?
end;

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

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

29
ответ дан 3 December 2019 в 14:54
поделиться
Другие вопросы по тегам:

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