Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Aynı türden iki class'ı nasıl klonlarız?
#1
Merhaba,

İki değişkenim (A ve B) ve bir class'ım (X) var. Bunlardan birisini (A'yı) çalıştırıp içini dolduruyorum. Diğerini (B'yi) ise A'dan birebir kopyalamak istiyorum. Bilinen bir yol yöntem var mı, Bunu nasıl yapabilirim?
YouTube Delphi Tips
"Yaşlanarak değil, yaşayarak tecrübe kazanılır. Zaman insanları değil, armutları olgunlaştırır" Peyami Safa
WWW
Cevapla
#2
(12-09-2018, Saat: 10:59)uparlayan Adlı Kullanıcıdan Alıntı: Merhaba,

İki değişkenim (A ve B) ve bir class'ım (X) var. Bunlardan birisini (A'yı) çalıştırıp içini dolduruyorum. Diğerini (B'yi) ise A'dan birebir kopyalamak istiyorum. Bilinen bir yol yöntem var mı, Bunu nasıl yapabilirim?

Create Edip, B:=A; demeniz yeterli değilmi? Yada

var
a,b:TXXClass;
begin
a:=TXXClass.Create;
b:=a.Create;
a.DegerA:='Njt';
a.DegerB:='Tajen';
bu şekilde olmuyormu?
WWW
Cevapla
#3
Yok, olmuyor üstad. Şöyle bir örnek vereyim;

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
 System.SysUtils;

type
 TNesne = class
   private
     FAd    : String;
     FSoyad : String;
   protected
   public
     property Ad     : String read FAd     write FAd;
     property Soyad  : String read FSoyad  write FSoyad;
 end;

var
 A, B: TNesne;
begin
 A       := TNesne.Create;
 A.Ad    := 'Uğur';
 A.Soyad := 'Parlayan';

 Writeln(' A = ' + A.Ad + ' ' + A.Soyad); // Mevcut değeri okuduk

 B := A;                                  // Atamayı yaptık
 B.Ad := 'Berkan';                        // Yeni değeri diğerine girdik
 Writeln(' B = ' + B.Ad + ' ' + B.Soyad); // Yeni değeri diğerinden okuduk
 Writeln(' A = ' + A.Ad + ' ' + A.Soyad); // Bu noktada A'nın Uğur PARLAYAN" sonucunu vermesi gerekiyor.
 Readln;
end.

C#'da "MemberWiseClone" diye bir yöntem var, delphi'de karşılığını bulamadım.
YouTube Delphi Tips
"Yaşlanarak değil, yaşayarak tecrübe kazanılır. Zaman insanları değil, armutları olgunlaştırır" Peyami Safa
WWW
Cevapla
#4
Aşağıdaki şekilde sorun çıkarmadan çalıştı hocam, bi deneyin isterseniz.

type
TNjtClass = class(tpersistent)
  private
     FDegerA : String ;
     FDegerB : String ;
  published
     property DegerA: String read FDegerA write FDegerA ;
     property DegerB: String read FDegerB write FDegerB ;
end;


procedure CopyObject(Source, Dest: TNjtClass);
var
 TypInfo: PTypeInfo;
 PropList: TPropList;
 PropCount, i: integer;
 Value: variant;
begin
 TypInfo := Source.ClassInfo;
 PropCount := GetPropList(TypInfo, tkAny, @PropList);
 for i := 0 to PropCount - 1 do
 begin
   Value := GetPropValue (Source, PropList [i]^.Name);
   SetPropValue (Dest, PropList [i]^.Name, Value);
 end;
end;


procedure TForm2.Button1Click(Sender: TObject);
var
a,b:TNjtClass;
begin
a:=TNjtClass.Create;
b:=TNjtClass.Create;
a.DegerA:='Njt';
a.DegerB:='Tajen';
memo1.Lines.Add(a.DegerA+' - '+a.DegerB);

CopyObject(a,b);
b.DegerA:=b.DegerA+'111';
b.DegerB:=b.DegerB+'111';
memo1.Lines.Add(b.DegerA+' - '+b.DegerB);
memo1.Lines.Add(a.DegerA+' - '+a.DegerB);

end;
WWW
Cevapla
#5
Üstad, Tokyo ile denemelerimi yaptığımda B'nin A'dan gelen değerleri saklamadığını gördüm, bir yandan da araştırmaya devam ediyordum JSON kullanarak sonuca ulaştım;

C#'daki MemberWiseClone metodunu Delphi'ye uyarladım ve sorunumu çözdüm, ilgin ve yardımın için teşekkür ederim.

implementation

uses
    System.JSON
  , Data.DBXJSONReflect
  , System.SysUtils
  ;

function MemberWiseClone(aNesne: TObject): TObject;
var
  TEMP        : TJSONValue;                                   //  Bu bizim ara nesnemiz, kopyalamak için kullanacağız
  Donusturucu : TJSONMarshal;                                 //  Bu bizim parametreyle gelen nesnemizin elemanlarını tarayacak
  Klon        : TJSONUnMarshal;                               //  Bu da bizim sonuç nesnemiz olacak.
begin
  Result      := nil;
  Klon        := TJSONUnMarshal.Create;                       //  Bu nesnenin içini dolduracağız
  Donusturucu := TJSONMarshal.Create;                         //  Bu, bizim asıl nesnemizi temsil eden ön işleyicili başka bir nesne
  try
    TEMP := Donusturucu.Marshal( aNesne );                    //  Nesnemizi JSON verisi haline dönüştürüyoruz
    try
      if Assigned(TEMP) then Result := Klon.Unmarshal(TEMP);  //  JSON verisini bir nesneye dönüştürüyoruz
    finally
      FreeAndNil(TEMP);
    end;
  finally
    FreeAndNil(Donusturucu);
    FreeAndNil(Klon);
  end;
end;

Şu şekilde kullanıyorum;


var
 A, B: TNesne;
begin
 A       := TNesne.Create;
 A.Ad    := 'Uğur';
 A.Soyad := 'Parlayan';
 
 Writeln(' A = ' + A.Ad + ' ' + A.Soyad); // Mevcut değeri okuduk

 B := TNesne( MemberWiseClone( A ) );
 
 // B := A;                               // BU SATIR İPTAL 

 B.Ad := 'Berkan';                        // Yeni değeri diğerine girdik
 Writeln(' B = ' + B.Ad + ' ' + B.Soyad); // Yeni değeri diğerinden okuduk
 Writeln(' A = ' + A.Ad + ' ' + A.Soyad); // Bu noktada A'nın Uğur PARLAYAN" sonucunu vermesi gerekiyor.
 Readln;
end.

YouTube Delphi Tips
"Yaşlanarak değil, yaşayarak tecrübe kazanılır. Zaman insanları değil, armutları olgunlaştırır" Peyami Safa
WWW
Cevapla
#6
Yazdığım şekilde Community Tokyo da sorunsuz çalışıyor hocam.
Uses TypInfo çağırdınızmı dicem ama gereksiz olucak.
Ayrıca class(tpersistent) olmasıda gerekiyor ama oda olmalı zaten sizde.
WWW
Cevapla
#7
(12-09-2018, Saat: 13:56)esistem Adlı Kullanıcıdan Alıntı: Yazdığım şekilde Community Tokyo da sorunsuz çalışıyor hocam.
Uses TypInfo çağırdınızmı dicem ama gereksiz olucak.
Ayrıca class(tpersistent) olmasıda gerekiyor ama oda olmalı zaten sizde.

Pardon, sıfırdan tekrar denediğimde sonuç aldım, hata için özür dilerim. En azından alternatif üretmiş olduk Smile
YouTube Delphi Tips
"Yaşlanarak değil, yaşayarak tecrübe kazanılır. Zaman insanları değil, armutları olgunlaştırır" Peyami Safa
WWW
Cevapla
#8
Bence class'a Copy yada Clone fonksiyonu yazmak daha güzel olur. Yada class yerine record kullanmak.
Yukarıda verilen örnek için söylüyorum; tek yapılması gereken
TNesne = class
yerine 
TNesne = record
yazmak.
There's no place like 127.0.0.1
WWW
Cevapla
#9
(12-09-2018, Saat: 16:48)SimaWB Adlı Kullanıcıdan Alıntı: Bence class'a Copy yada Clone fonksiyonu yazmak daha güzel olur. Yada class yerine record kullanmak.
Yukarıda verilen örnek için söylüyorum; tek yapılması gereken
TNesne = class
yerine 
TNesne = record
yazmak.

Bir makaleye altyapı olsun diye sorulan bir soruydu ve verilen örnek soruyu basitleştirmek için o şekilde kurgulanmıştı.
YouTube Delphi Tips
"Yaşlanarak değil, yaşayarak tecrübe kazanılır. Zaman insanları değil, armutları olgunlaştırır" Peyami Safa
WWW
Cevapla
#10
O zaman sabırsızlıkla makaleyi bekliyoruz Wink
There's no place like 127.0.0.1
WWW
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Uygulamaya responsive görünüm nasıl kazandırabilriz ? delphicim 0 202 04-01-2024, Saat: 15:24
Son Yorum: delphicim
  Delphi 7 ye göre MB Döviz kurları nasıl alırız maydin60 7 964 31-12-2023, Saat: 02:18
Son Yorum: maydin60
  ReadProcessMemory ile veri okuma nasıl yapılır eraendless 2 413 07-09-2023, Saat: 00:35
Son Yorum: veteran
  ARRAYi nasıl for'la dönerim. PREDATOR 16 9.877 26-08-2023, Saat: 14:33
Son Yorum: veteran
  Yandex Disk üzerinden TIdWebDAV ile nasıl dosya alabilirim adelphiforumz 2 843 17-03-2023, Saat: 16:53
Son Yorum: adelphiforumz



Konuyu Okuyanlar: 1 Ziyaretçi