开发者

Delphi How to use types from other forms?

开发者 https://www.devze.com 2023-02-17 13:52 出处:网络
Sorry this is a very newbie question. We have this massive application I am doing maintenance on.It has 5 d开发者_JS百科ifferent forms.We put our global variables in one unit (uGlobal).But i can\'t s

Sorry this is a very newbie question.

We have this massive application I am doing maintenance on. It has 5 d开发者_JS百科ifferent forms. We put our global variables in one unit (uGlobal). But i can't seem to access it from the data unit (uData).

I have this:

Unit uGlobal
type
TmyType: (alpha, beta);
...

Unit uGlobal

Stuff:  TmyType  <- error, undeclared indentifier

When i try to put uGlobal in the uses section of uData, it complains of a circular reference. So, kinda clueless here. They are both in the same project. This is using BDS 2006.


You have a circular reference because you have things in uGlobal that want to make use of things in uData and vice-versa. Circular references are a big concern in large projects because they greatly increase complexity - if you have circular dependencies, it becomes more like one BIGGER unit. I suspect you have a long way to go before your project can be considered large, let alone "massive". ;)

You have 2 possible solutions:

  • Go with the circular dependency, making one dependency weak, and the other strong.
  • Apply a little redesign to eliminate the problem alogether. (Break things into smaller chunks.)

Keeping the circular dependency

David has already given the answer: At least one of the units must use the other from the implementation section.

  • A uses B uses A is absolutely not allowed, but you can think of the interface and implementation sections as being almost like separate units themselves (with a bunch of special referencing rules).
  • So ask yourself what does each sub-unit need?
  • If for example:
    • You declared a type in uData interface and referenced that in uGlobal interface, then the interface of uGlobal needs uData and will need a corresponding uses clause.
    • If there's a type in uData implementation that's referenced in anywhere uGlobal, then that declaration in uData implementation must be moved to the interface section.
    • If there's a type in uGlobal interface must it's only referenced from the implementation section of uData then that uses clause will be fine in the implementation section.
  • If you have the unfortunate situation that types in both interface sections reference types in the other interface section, then you have to to modularise a little more by applying the technique to Remove Circular Dependency.

Remove Circular Dependency

Removing the circular dependency requires breaking your units down into smaller ones that are more manageable. To do this, you must understand the dependencies between each of the things in your application. For example:

  • Suppose uGlobal declares A and C
  • A depends on C, but C doesn't need A
  • Suppose also that uData declares B which needs C
  • But it turns out that A also needs B
  • This is why you have the circular dependency

All you have to do in this case is declare a new unit at move C in there.

  • Then both uGlobal and uData will use uNewUnit
  • But neither will need the other
  • And your circular dependency will be removed entirely.

Disclaimer

I am not in any way advocating your approach with uGlobal. In fact it is a very bad idea and will bite you big time on 2 fronts when your projects starts to get large. Unfortunately the explanation is a mammoth answer in itself.

  • Use of global variables at all is dangerous and to be avoided.
  • Use of 'big dumping units' like uGlobal and uData is also dangerous, and you've only just satrted to experience their problems.


Use the second 'uses', the one in the 'implementation' section

unit uData;

uses SysUtils, etc;

type
  etc;

implementation

uses uGlobal;

// here you can reference things in uGlobal


Generally David Zimmerman's answer is the way to go, but in your case (according to your response to David's answer), you need TMyType in the interface section of uGlobal unit; therefore adding uData to uses clause of the implementation section won't help.

Seems it is time for refactoring; you should consider moving TMyType or Stuff into a third unit, so that both uData and uGlobal can reference to it.

0

精彩评论

暂无评论...
验证码 换一张
取 消