Перейти к содержанию
Fire Monkey от А до Я
  • 0

Установить значение типу <T>


rareMax

Вопрос

Как в результат функции установить значение? Ниже набросок функции которая возвращает массив значений с типом переданным пользователем: 

function TArrayHelper<T>.Generate(const Count: Integer): TArray<T>;
var
  Info: PTypeInfo;
  I: Integer;
  AI: TArray<Integer>;
begin
  Info := System.TypeInfo(T);
  SetLength(Result, Count);
  // Для дробных
  if Info.Kind = TTypeKind.tkFloat then
    for I := Low(Result) to High(Result) do
      Result[I] := Random;
  // Для целых
  if Info.Kind = TTypeKind.tkInteger then
    for I := Low(Result) to High(Result) do
      Result[I] := Random(100);
end;

 Вообще такое можно сделать? Или лучше будет(хотя не мне это не очень то и нравится) сделать что бы возвращала функция массив вариантов:

function TArrayHelper<T>.Generate(const Count: Integer): TArray<TValue>;

Надеюсь суть вопроса понятна. 

 

Ссылка на комментарий

Рекомендуемые сообщения

  • 0

Еще разок спрошу - вообще можно так делать или нет? Например что то типа такого. 

function TgdmUtils.ValueAs<T>(const Value: TValue): T;
begin
  case PTypeInfo(System.TypeInfo(T)).Kind of
    TTypeKind.tkInteger:
      Result := Value.AsString.ToInteger;
    TTypeKind.tkFloat:
      Result := Value.AsString.ToSingle;
  end;
end;

 

Ссылка на комментарий
  • 0
Result := Value.AsString.ToInteger;

А попроще нельзя? Не запущена среда, но разве нет Value.AsInteger? Если с целыми числами преобразование пройдет нормально (хоть и с лишними телодвижениями в виде "сперва в строку а потом в int"), то в случае вещественных чисел вы рискуете потерять часть данных.

Ссылка на комментарий
  • 0
2 часа назад, krapotkin сказал:

ну а компилятор-то что говорит?

Цитата

[dcc32 Error] gdmUtils.pas(25): E2010 Incompatible types: 'T' and 'Integer'
[dcc32 Error] gdmUtils.pas(27): E2010 Incompatible types: 'T' and 'Single'

------------------

2 часа назад, kami сказал:

А попроще нельзя? Не запущена среда, но разве нет Value.AsInteger? Если с целыми числами преобразование пройдет нормально (хоть и с лишними телодвижениями в виде "сперва в строку а потом в int"), то в случае вещественных чисел вы рискуете потерять часть данных.

Заранее известно, что в Value точно будет храниться данные в виде строки.  

Value.AsInteger - да, такое есть. Но такое будет работать при условии, что в TValue вносились данные в виде целого числа - например Value:=5; 

Такая конструкция - выдаст ошибку:  

var LInteger:Integer;
Begin
Value:='542'; 
LInteger:=Value.AsInteger

И если бы так можно было - конвертировать данные - это было бы чудо)

Извиняюсь что сразу не все написал в теме

 

Изменено пользователем Сысоев Максим
Ссылка на комментарий
  • 0
34 минуты назад, dnekrasov сказал:

А что Вам мешает использовать TValue.AsType<T> ?

Думаю, что мешает это:

2 часа назад, Сысоев Максим сказал:

Заранее известно, что в Value точно будет храниться данные в виде строки.  

 

Ссылка на комментарий
  • 0
Цитата

Заранее известно, что в Value точно будет храниться данные в виде строки

Sorry, не заметил.

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

Ссылка на комментарий

Присоединяйтесь к обсуждению

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

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

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...