Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Type mit in andere Unit durchreichen...? (https://www.delphipraxis.net/55615-type-mit-andere-unit-durchreichen.html)

Tonic1024 24. Okt 2005 11:41


Type mit in andere Unit durchreichen...?
 
Hi...

Ich hab wieder einmal ein Problem, bei dem es mir schwer fällt es in Worte zu fassen... Ist auch kein richtiges Problem, mehr eine "Unschönheit" :wink:

Ich habe eine Klasse entwickelt, die einen (evtl bald mehrere) Thread (TThread) benutzt. Ich brauche dafür nen selbstgebastelte Typ, den ich um ihn "quasiglobal" zu nutzen, in eine Extra-Unit gepackt habe.

Delphi-Quellcode:
unit ModemStuff; // Aussagekräftigen Namen ausdenken... <!>

interface

type TModemResult = (mrNIL, mrError, mrOkay, mrPrompt, mrTimeOut);
{..}

implementation
{..}

end.
"ModemStuff" ist in den Uses-Klauseln der Thread-Units und der Klassen-Unit aufgeführt. Wenn ich in einem Programm nun diese Klasse verwenden will, muss ich in die Uses-Klauses des Programms sowohl die Klassen- als auch die Typen-Unit aufführen. Macht ansich nix, ich möchte aber den zukünftigen Usern dieser Unit aber keine potentiellen Fehlerquellen einbauen. Aus Gründen der Übersicht will ich aber auch nicht den ganzen quatsch in eine Unit kloppen.

Gibts da ne Lösung? Eine "schöne" Lösung? :-D

MfG

Toni

Flocke 24. Okt 2005 12:05

Re: Type mit in andere Unit durchreichen...?
 
(ungetestet)
Delphi-Quellcode:
unit ThreadStuff;

uses
  ModemStuff;

type
  TModemResult := ModemStuff.TModemResult;

Tonic1024 24. Okt 2005 12:20

Re: Type mit in andere Unit durchreichen...?
 
Gute Idee...

Hatte ich aber auch schon. Da bewirkt das TModemResult zwar bekannt ist, nicht jedoch mrOkay... Irgendwie verwirrend...


[Edit] Mit "=" statt ":=" probiert...[/Edit]

NicoDE 24. Okt 2005 12:32

Re: Type mit in andere Unit durchreichen...?
 
Zitat:

Zitat von Tonic1024
Gibts da ne Lösung? Eine "schöne" Lösung?

'Schön' wird schwierig...
Die Definitionen würden sich dann in zwei Namensräumen befinden. Die Delphi Language bietet aber kein Sprachelement um Typdeklarationen in andere Namensräume zu übernehmen. Eine Lösung könnte auf Includes basieren (was nicht 'schön' ist :)).

Tonic1024 24. Okt 2005 12:45

Re: Type mit in andere Unit durchreichen...?
 
Ja, soweit war ich auch schon... Den Gedanken hab ich ansich schon in dem Moment verworfen als er mir kam....

NicoDE 26. Okt 2005 18:20

Re: Type mit in andere Unit durchreichen...?
 
Zitat:

Zitat von Tonic1024
Ja, soweit war ich auch schon... Den Gedanken hab ich ansich schon in dem Moment verworfen als er mir kam....

Weise Entscheidung :D
Sowas kann 'unschöne' Ausmaße annehmen... habe mal ein altes Test-Template herausgesucht:
Delphi-Quellcode:
{$ifndef read_implementation}
  {$ifndef read_interface}

unit Unit1;

interface

//
// Interface uses here
// (must also use all units which are required by the units included below)
//

  {$endif !read_interface}
  {$ifndef included_interface_UNIT1}
  {$define included_interface_UNIT1}
    {$ifndef read_interface}
    {$define read_interface}
    {$define read_interface_UNIT1}
    {$endif !read_interface}

//
// Interface includes here
// (included units must support read_interface/read_implementation defines)
//

    {$ifdef read_interface_UNIT1}
    {$undef read_interface_UNIT1}
    {$undef read_interface}
    {$endif read_interface_UNIT1}

//
// Interface here
//

  {$endif !included_interface_UNIT1}
  {$ifndef read_interface}

implementation

//
// Implementation uses here
// (must also use all units which are required by the units included below)
//

  {$endif !read_interface}
{$endif !read_implementation}
{$ifndef read_interface}
  {$ifndef included_implementation_UNIT1}
  {$define included_implementation_UNIT1}
    {$ifndef read_implementation}
    {$define read_implementation}
    {$define read_implementation_UNIT1}
    {$endif !read_implementation}

//
// Implementation includes here
// (included units must support read_interface/read_implementation defines)
//

    {$ifdef read_implementation_UNIT1}
    {$undef read_implementation_UNIT1}
    {$undef read_implementation}
    {$endif read_implementation_UNIT1}

//
// Implementation here
//

  {$endif !included_implementation_UNIT1}
  {$ifndef read_implementation}
    {$warnings off}  // [Warning]: Text after final 'END.' - ignored by compiler
end.
  {$endif !read_implementation}
{$endif !read_interface}
(nicht unbedingt zur Nachahmung empfohlen - dann kann man auch gleich in C programmieren ;))

himitsu 26. Okt 2005 18:57

Re: Type mit in andere Unit durchreichen...?
 
Eventuell ja so?
(hab bisher auch noch keine Konstanten/Variablen weitergegeben -.-'')
Aber das mit dem Type ist schon richtig so (es funktioniert zumindestens ... und natürlich mit =, da es ja um 'ner Typenzuweisung geht)
Delphi-Quellcode:
unit ThreadStuff;

uses
  ModemStuff;

type
  TModemResult = ModemStuff.TModemResult;

const
  mrNILmrError = ModemStuff.mrNILmrError;
  mrOkay      = ModemStuff.mrOkay;
  mrPrompt    = ModemStuff.mrPrompt;
  mrTimeOut   = ModemStuff.mrTimeOut;
Am Sichersten wäre es aber bestimmt so.
Delphi-Quellcode:
unit ThreadStuff;

uses
  ModemStuff;

type
  TModemResult = ModemStuff.TModemResult;

const
  mrNILmrError = TModemResult(ModemStuff.mrNILmrError);
  mrOkay      = TModemResult(ModemStuff.mrOkay);
  mrPrompt    = TModemResult(ModemStuff.mrPrompt);
  mrTimeOut   = TModemResult(ModemStuff.mrTimeOut);
PS: hab Derzeit kein Delphi, also vollkommen ungetestet.

Tonic1024 28. Okt 2005 10:45

Re: Type mit in andere Unit durchreichen...?
 
Hi Himitsu...

Schöne Lösung, nur leider völlig an meinem Problem vorbei :-D Dann müsste ja de User, der garnicht weiss/ nicht wissen muss wie die Modem-Komponente arbeitet auch den const-teil in seinem Code eingeben, was ich ja verhindern will. Der soll ja garnichts machen...


Aber... *grübel* :gruebel:

Wenn ich die Type in der "Haupt-Unit" mit der Klasse für den Userzurgiff definiere und nur intern deine Lösung verwende... *HektischPapierUndBleistiftRauskram* - Werd ich ausprobieren... Danke.


Toni

Schwedenbitter 11. Nov 2014 15:37

AW: Re: Type mit in andere Unit durchreichen...?
 
Zitat:

Zitat von Tonic1024 (Beitrag 378131)
Hi Himitsu...
Aber... *grübel* :gruebel:

Wenn ich die Type in der "Haupt-Unit" mit der Klasse für den Userzurgiff definiere und nur intern deine Lösung verwende... *HektischPapierUndBleistiftRauskram* - Werd ich ausprobieren... Danke.

Gibt es denn schon eine Lösung für das Problem?
Diese würde mich wirklich brennend interessieren.

Gruß, Alex

Thomas_K 12. Nov 2014 10:28

AW: Type mit in andere Unit durchreichen...?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier ist auf die Schnelle mein Lösungsvorschlag:

Die Unit der den Type beinhält, aber in einer Klasse versteckt.
Code:
unit UnitTypeClass;

interface

type
  TTypeClass = class
    type
      TModemResult = (mrNIL, mrError, mrOkay, mrPrompt, mrTimeOut);
  end;

implementation

end.
Hier die Unit mit der Klasse, die nur der Anwender nutzen soll.
Code:
unit UnitUserClass;

interface

uses
  UnitTypeClass;

type
  TUserClass = class(TTypeClass)
  private
    FModemResult: TTypeClass.TModemResult;
  public
    property ModemResult: TTypeClass.TModemResult read FModemResult write FModemResult;
  end;

implementation

end.
Und schlussendlich das Anwenden der User Klasse.
Code:
uses
  UnitUserClass;

procedure TMainForm.ButtonTestClick(Sender: TObject);
var
  UserClass: TUserClass;
begin
  UserClass := TUserClass.Create;
  try
    UserClass.ModemResult := TUserClass.TModemResult.mrNIL;
  finally
    UserClass.Free;
  end;
end;
Das Ganze noch einmal als fertiges Projekt zum Runterladen.

DeddyH 12. Nov 2014 10:45

AW: Type mit in andere Unit durchreichen...?
 
Kannte denn Delphi 2006 bzw. Turbo Delphi schon Nested Types?

Dejan Vu 12. Nov 2014 10:46

AW: Type mit in andere Unit durchreichen...?
 
Also ich finde das verwirrend. Da wird ein Datentyp deklariert, den man aber nicht verwenden soll, sondern einen anderen, der aber genau das gleiche ist. Wenn man das aber doch machen sollte, funktioniert das dann doch gar nicht mehr, oder irre ich mich? So wie der Threadersteller von 9 Jahren meinte, er möchte keine Fehlerquellen einbauen, geht es doch gar nicht. Man kann doch eher so Fehlerquellen einbauen (einfach beide Units importieren und versehentlich den anderen Datentyp verwenden).

Was sollen diese Klimmzüge? Wenn der Typ separat deklariert ist, dann verwende ich eben diese Unit explizit. Oder ich mappe sie explizit, aber so verstecken? Nur weil ich nur eine Unit importieren will? Ich könnte auch einfach alle Threads in eine Unit schmeißen, wenn es also darum ginge, wäre das die einfachste Art. Macht die VCL ja auch so...

Thomas_K 12. Nov 2014 11:28

AW: Type mit in andere Unit durchreichen...?
 
Zitat:

Zitat von DeddyH (Beitrag 1279445)
Kannte denn Delphi 2006 bzw. Turbo Delphi schon Nested Types?

Ich verwende Nested Types mindesten seit Delphi 6, ganz unproblematisch ist aber die Sache nicht, in neueren Delphi-Versionen lässt sich damit relativ einfach die Quellcode-Vervollständigung außer Kraft setzen. Dann muss man halt etwas mit zusätzlichen und eigentlich überflüssigen Klassen direktiven(protected,private,public) experimentieren, bzw. andere Kopfstände machen.

p80286 12. Nov 2014 12:34

AW: Type mit in andere Unit durchreichen...?
 
Zitat:

Zitat von Dejan Vu (Beitrag 1279446)
Also ich finde das verwirrend. Da wird ein Datentyp deklariert, den man aber nicht verwenden soll, sondern einen anderen, ...

Wenn ich das richtig verstanden habe, geht es darum eine Unit mit Typ (und anderen) Deklarationen für den Benutzer "unsichtbar" einzubinden. Hätte ich auch gerne, scheint aber nicht machbar zu sein.

Gruß
K-H

Sir Rufo 12. Nov 2014 12:55

AW: Type mit in andere Unit durchreichen...?
 
Geht doch einwandfrei ... ob es sinnvoll ist, steht ja auf einem anderen Blatt :)
Delphi-Quellcode:
unit MyLib.Types;

interface

// Nicht notwending, aber nach dem Durchreichen muss eh mit TSomeType.stNothing gearbeitet werden.
{$SCOPEDENUMS ON}

type
  TSomeType = ( stNothing, stVery, stUseful );

implementation

end.
Delphi-Quellcode:
unit MyLib.Core;

interface

uses
  MyLib.Types;

type
  TMyCore = class
  public
    constructor Create( AType: TSomeType );
  end;

implementation

{ TMyCore }

constructor TMyCore.Create( AType: TSomeType );
begin
  inherited Create;

end;

end.
Zusammenfassen:
Delphi-Quellcode:
unit MyLib;

interface

uses
  MyLib.Types,
  MyLib.Core;

type
  TSomeType = MyLib.Types.TSomeType;
  TMyCore = MyLib.Core.TMyCore;

implementation

end.
Verwenden:
Delphi-Quellcode:
program dp_055615;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  MyLib in 'MyLib.pas';

procedure Main;
var
  LInstance: TMyCore;
begin
  LInstance := TMyCore.Create( TSomeType.stNothing );
  try

  finally
    LInstance.Free;
  end;
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln( E.ClassName, ': ', E.Message );
  end;
  ReadLn;

end.

Stevie 12. Nov 2014 14:17

AW: Type mit in andere Unit durchreichen...?
 
Zitat:

Zitat von Thomas_K (Beitrag 1279453)
Ich verwende Nested Types mindesten seit Delphi 6

Garantiert nicht, die kamen erst nach Delphi 7.

Thomas_K 13. Nov 2014 14:59

AW: Type mit in andere Unit durchreichen...?
 
Zitat:

Zitat von Stevie (Beitrag 1279475)
Zitat:

Zitat von Thomas_K (Beitrag 1279453)
Ich verwende Nested Types mindesten seit Delphi 6

Garantiert nicht, die kamen erst nach Delphi 7.

Erwischt, ich habe unter Delphi 6 nur ein paar Records innerhalb einer Klasse erzeugt. Für Records brauch man nicht unbedingt type verwenden, solange man es nur einmal innerhalb eines Objektes benötigt.

himitsu 13. Nov 2014 16:15

AW: Type mit in andere Unit durchreichen...?
 
Zitat:

Zitat von Thomas_K (Beitrag 1279662)
Erwischt, ich habe unter Delphi 6 nur ein paar Records innerhalb einer Klasse erzeugt. Für Records brauch man nicht unbedingt type verwenden, solange man es nur einmal innerhalb eines Objektes benötigt.

Record-Variablen oder wirklich Typen?

Wie bereits erwähnt, dürfte der Typ nicht gehen.

Delphi-Quellcode:
type
  TMyRecord = record
    i: Integer;
    S: string;
  end;

  TMyClass = class
  public type
    TMyInnerRecord = record
      i: Integer;
      S: string;
    end;
  public
    FFieldInner: TMyRecord;
    FFieldOuter: TMyInnerRecord;
    FFieldDirect: record
      i: Integer;
      S: string;
    end;
  end;

var
  MyGlobalVarInner: TMyRecord;
  MyGlobalVarOuter: TMyClass.TMyInnerRecord;
  MyGlobalVarDirect: record
    i: Integer;
    S: string;
  end;
Die Inlinedeklaration geht schon lange, sonst müsste man auch bei jedem
Delphi-Quellcode:
array of ...
das erstmal als eigenen Typen deklarieren, bevor man damit eine Variable definieren kann.

Dejan Vu 13. Nov 2014 19:05

AW: Type mit in andere Unit durchreichen...?
 
Zitat:

Zitat von Sir Rufo (Beitrag 1279462)
Geht doch einwandfrei ... ob es sinnvoll ist, steht ja auf einem anderen Blatt :)

Wie immer gut erklärt und durch den Einwurf 'ob es sinnvoll ist...' auch in der richtigen Ecke gelandet.

Es bleibt dabei (für mich): Will ich mir einen abbrechen, nur um ein glasklares und stringentes 'uses' zu unterbinden? Verzichte ich auf Messer, Gabel und Löffel, damit ich mir noch mit -der Einfachheit wegen- Gameffel hantieren muss? Ist das wirklich einfacher? Muss jeder selbst entscheiden.

Stevie 13. Nov 2014 23:21

AW: Type mit in andere Unit durchreichen...?
 
Zitat:

Zitat von Dejan Vu (Beitrag 1279692)
Zitat:

Zitat von Sir Rufo (Beitrag 1279462)
Geht doch einwandfrei ... ob es sinnvoll ist, steht ja auf einem anderen Blatt :)

Wie immer gut erklärt und durch den Einwurf 'ob es sinnvoll ist...' auch in der richtigen Ecke gelandet.

Es bleibt dabei (für mich): Will ich mir einen abbrechen, nur um ein glasklares und stringentes 'uses' zu unterbinden? Verzichte ich auf Messer, Gabel und Löffel, damit ich mir noch mit -der Einfachheit wegen- Gameffel hantieren muss? Ist das wirklich einfacher? Muss jeder selbst entscheiden.

Ich finde das teilweise schon praktisch. Gerade unter Berücksichtigung, dass es in Delphi keine richtigen Namespaces gibt. Da kann ich nich einfach
Delphi-Quellcode:
uses MeineLib
schreiben sondern muss die drölfzig Units, aus denen ich was brauche einzeln "usen". Natürlich nur ein stümperhafter Behelf aus Mangel an Alternativen :(

Dejan Vu 14. Nov 2014 03:50

AW: Type mit in andere Unit durchreichen...?
 
Daran hab ich auch gedacht ('Namespaces'), aber mir dann gesagt: Wenn man schon bei Delphi ist, dann soll man imho die Sprache doch so nutzen, wie sie gedacht ist... Also 'Units' als Vorgänger der Namespaces mit allen Eigenheiten, so wie hier. Da hat man dann eben nicht drölfzig (oder sogar einundrölfzig!) Units, sondern genau: 2 (Typ und Klassen).

Andere Möglichkeit: Eine Unit für den Typen, Interfaces der Threads und eine Factory. Threadklassen melden sich in der Factory an. Anwender bindet nur die Typ-Unit ein und holt sich die Instanzen über die Factory.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:12 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz