title: Delphi - Change field to calculated field at runtime. Is this a good practice?
body: <p>As in the question's title, I argue with a colleague about how calculated fields should be used. 
  From my knowledge, calculated fields are created at runtime as in the François's <a href="https://stackoverflow.com/a/2525553/368364">answer</a> on the question <a href="https://stackoverflow.com/questions/2523697/adding-a-calculated-field-to-a-query-at-run-time/2525553#2525553">Adding a calculated field to a Query at run time</a>. On the same question there is another <a href="https://stackoverflow.com/a/2526972/368364">answer</a>, from sabri.arslan which suggest to change an existing field to a calculated one(code bellow) </p>
  
  <pre><code>var
   initing:boolean;
  
  procedure TSampleForm.dsSampleAfterOpen(
    DataSet: TDataSet);
  var
   i:integer;
   dmp:tfield;
  begin
  if not initing then
   try
    initing:=true;
    dataset.active:=false;
    dataset.FieldDefs.Update;
    for i:=0 to dataset.FieldDefs.Count-1 do
    begin
     dmp:=DataSet.FieldDefs.Items[i].FieldClass.Create(self);
     dmp.FieldName:=DataSet.FieldDefs.Items[i].DisplayName;
     dmp.DataSet:=dataset;
     if (dmp.fieldname='txtState') or (dmp.FieldName='txtOldState') then
     begin
       dmp.Calculated:=true;
       dmp.DisplayWidth:=255;
       dmp.size:=255;
     end;
    end;
    dataset.active:=true;
   finally
    initing:=false;
   end;
  end;
  
  procedure TSampleForm.dsSampleAfterClose(
    DataSet: TDataSet);
  var
   i:integer;
   dmp:TField;
  begin
  if not initing then
  begin
   for i:=DataSet.FieldCount-1 downto 0 do
   begin
    dmp:=pointer(DataSet.Fields.Fields[i]);
    DataSet.Fields.Fields[i].DataSet:=nil;
    freeandnil(dmp);
   end;
   DataSet.FieldDefs.Clear;
  end;
  end;
  
  procedure TSampleForm.dsSampleCalcFields(
    DataSet: TDataSet);
  var
   tmpdurum,tmpOldDurum:integer;
  begin
    if not initing then
      begin
        tmpDurum := dataset.FieldByName( 'state' ).AsInteger;
        tmpOldDurum:= dataset.FieldByName( 'oldstate' ).AsInteger;
        dataset.FieldByName( 'txtState' ).AsString := State2Text(tmpDurum);
        dataset.FieldByName( 'txtOldState' ).AsString := State2Text(tmpOldDurum);
      end;
  end;
  
  procedure TSampleForm.btnOpenClick(Sender: TObject);
  begin
   if dsSample.Active then
     dsSample.Close;
   dsSample.SQL.text:='select id,state,oldstate,"" as txtState,"" as txtOldState from states where active=1';
   dsSample.Open;
  end;
  </code></pre>
  
  <p>I believe that this change leads to an unknown behavior of the specified TField. It is safe to change a dataset field to a calculated one on the runtime? What kind of issues can this generate?</p>
  
  <p>LE: This is a question. Its purpose it is to demonstrate good practice on adding a calculated field on a dataset at runtime. And, yes adding a calculated field at runtime is bad design. </p>
  
  <p>LE2: This is only an example for 'do not this in this way'. As an argument I asked what is the behavior of the field in discussion after doing this. How that field will act?</p>